EE308FZ lab2_2

对方正在摸鱼中 2022-11-18 23:44:57
The Link Your Classhttps://bbs.csdn.net/forums/MUEE308FZU202201
The Link of Requirement of This Assignmenthttps://bbs.csdn.net/topics/608859318
MU STU ID and FZU STU IDFZU ID : 832001124    MU ID : 20124732

Teammate's MU STU ID and FZU STU ID

MU ID : 20123108  20122292      FZU ID :832001302  832001321

Teammate's blog Link

https://bbs.csdn.net/topics/609107422

https://bbs.csdn.net/topics/609330022

GitHub Linkhttps://github.com/fish-Rita/bobing/tree/master
Video demo Linkhttps://www.bilibili.com/video/BV1gd4y1b7Hq
Online Game Linkhttp://47.122.44.9:5678/

 

Contents

1.PSP Table

2.Keep track of progress bar

3.Our design results  

4.Key functions & Programming Thinking

5.Thing Take Long Time to Finish

6.GitHub Link and Commit Record  

7.Program Experience Great Gain


 

1.PSP Table

PSPESTIMATE TIME(MINUTE)ESTIMATE TIME(MINUTE)
Planning4530
 Estimate55
Development3050
Analysis6070
Design Spec1010
 Design Review00
 Coding Standard2015
Design4060
Coding240300
Code Review1015
 Test6080
Reporting\\
 Test Report1020
Size Measurement1010
Postmortem & Process Improvement Plan2050
Total560715

 


 

2.Keep track of progress bar

Time(Week 11)

New Coding LineAccumulated Elapsed Time(mins)What we have done
10480Learn the css and html language individually
2100840

Learning the basis of python flusk to arrange back end

33001260Start to write the function of logging and registering
45001800Use js language to write the judement of resuls of dices in various modes and finish writing the front end
51002160Test the code and upload it to the Aliyun server
67802520Record App video and final test our program

 


 

3.Our design results  

 The video demonstration of our software applet has already uploaded on bilibili and the Link is:

https://www.bilibili.com/video/BV1gd4y1b7Hq/?spm_id_from=333.999.0.0&vd_source=221825654697daa6d6cfd24219ca8ed1

Online game link is:

http://47.122.44.9:5678/

 

There are some worth mentioning points are as follows 😛😜😝:

  • We successfully pakage and upload the applet into the Aliyun server. 

 

  • We designed the login page according to the idea of the interaction prototype designed by lab2-1, and provide different jumps according to different osscasions. In order to achieve login in more easier, we store the data entered by the user in an array object,

 

  • We accomplish the record of history grades based on scores and design a ranking list among player NO1.~NO.5 according to the scores.

  • We implemented the random appearance of 6 dice, set the layout of different positions and angles of dices, make the picture more realistic and vivid, and can achieve dice clearing and reset.

 

  • We restored the  Axure prototype we designed in Lab2-1 to a great extent, and retained the small details we carefully designed at that time, such as real-time viewing of the rules of the game and recording of the ranking accoding to the scores per player. In addition, we also used the background of the GIF to make the whole picture more beautiful.

 

4.Key functions & Programming Thinking

4.1 Deal with back end programs to achieve login and register

We use python flask to reach the register and login function, and verify whether the information menu submitted by the user is legal or not, if it can not meet the specifications and requirements, it will be intercepted 👇.

class LoginForm(FlaskForm):
    """登录表单类"""
    username = StringField('Username', validators=[DataRequired()])
    password = PasswordField('Password', validators=[DataRequired()])


class RegisterForm(FlaskForm):
    email = StringField("Email", validators=[DataRequired(), Length(1, 64)])
    username = StringField(
        "Username",
        validators=[
            DataRequired(),
            Length(1, 64),
            Regexp(
                "^[A-Za-z][A-Za-z0-9_.]*$",
                0,
                "Usernames must have only letters, " "numbers, dots or underscores",
            ),
        ],
    )
    password = PasswordField(
        "Password",
        validators=[
            DataRequired(),
            EqualTo("password_confirmation", message="Passwords must match."),
        ],
    )
    password_confirmation = PasswordField("Confirm password", validators=[DataRequired()])
    submit = SubmitField(label="Register")

Once the user finish registering, we start to deal with the user information. Initially, we use the method of Cryptographic Hash Function to encrypt the user information and store it into the database. When the user finish logging, the password submitted by the user will be compared with the exsisting hashed passwords. Then we make session to record the user message 👇.

@app.route('/login', methods=['GET', 'POST'])  # 登录
def login():
    form = LoginForm()
    if request.method == 'GET':
        return render_template('login.html', form=form)
    user_name = form.username.data
    password = form.password.data
    user_info = get_user(user_name)  # 从用户数据中查找用户记录
    if user_info is None:
        emsg = "please enter username or password"
        return render_template('login.html', err=emsg)
    else:
        user = User(user_info[0])  # 创建用户实体
        if check_password_hash(user.password_hash, password):  # 校验密码
            login_user(user)
            return redirect(url_for('index'))
        else:
            emsg = "username or password error!"
            return render_template('login.html', err=emsg)


@app.route("/register", methods=["GET", "POST"])
def register():
    if request.method == 'GET':
        return render_template('register.html')
    form = RegisterForm()
    if not form.username.data or not form.password.data or not form.email.data:
        emsg = "please enter the message"
        return render_template('register.html', err=emsg)
    sql = "insert into users(username, password, email, money) " \
          "VALUES ('%s', '%s', '%s', '%d')" % \
          (form.username.data, generate_password_hash(form.password.data), form.email.data, 0)
    try:
        cursor.execute(sql)
        conf.db.commit()

    except pymysql.err.InterfaceError as e:
        print(e, type(e))
        conf.db.ping(True)

    except AttributeError:
        conf.e()
        logging.error(AttributeError)
    return redirect(url_for('login'))

4.2.Achieving the function of different game modes

For this part, we designed an algorithm based on the game rules to calculate the player's score and used ajax to dynamically send the data from the front end to the back end. Then, we store it into the database 👇.

Single player: 

@app.route('/individual', methods=['GET'])
@login_required
def individual():
    get_point = request.args.get('point')
    sql = f"select money from users where username = '{current_user.username}'"
    try:
        cursor.execute(sql)
        conf.db.commit()
        result = cursor.fetchall()
        if result:
            plus = result[0][0] + int(get_point)
            sql_update = f"update users set money = '{plus}' where username = '{current_user.username}'"
            cursor.execute(sql_update)
            conf.db.commit()

    except pymysql.err.InterfaceError as e:
        print(e, type(e))
        conf.db.ping(True)

    except Exception as e:
        conf.e()
        logging.error(e)

    return render_template('individual.html')

 Multiple playes:

// 掷骰子的功能
function rollTheDice() {
setTimeout(function () {
if (document.getElementById("b1").innerText === "Open") {
open()
} else {
for (var i=0; i<2; i++) {
if (points[i] === -1) {
clear()
stop(i)
break
}
}
if (points[points.length-1] !== -1) {
if (points[0]===points[1]) {
document.querySelector("h3").innerHTML = "draw!"
} else {
points[0] > points[1] ?
document.querySelector("h3").innerHTML = "player 1 win!" :
document.querySelector("h3").innerHTML = "player 2 win!"
        }
        points=[-1,-1]}
      }
   },1000)
}

4.3 Design the ranking list based on history records

The usernames and scores of the top five users No.1-No.5 are sorted by MySQL and then we connect it to the front end page 👇.

@app.route('/ranking', methods=['GET'])
@login_required
def ranking():
    sql = "select username, money from users order by money desc limit 5"
    try:
        cursor.execute(sql)
        conf.db.commit()
        result = cursor.fetchall()

    except pymysql.err.InterfaceError as e:
        print(e, type(e))
        conf.db.ping(True)
        return render_template('test.html')

    except Exception as e:
        conf.e()
        logging.error(e)
        return render_template('test.html')
    if len(result) >= 5:
        return render_template('ranking.html',
                               u1=result[0][0], m1=result[0][1],
                               u2=result[1][0], m2=result[1][1],
                               u3=result[2][0], m3=result[2][1],
                               u4=result[3][0], m4=result[3][1],
                               u5=result[4][0], m5=result[4][1]
                               )
    else:
        return render_template('test.html')

This is a basic user class that inherits the accumulation of users from the flask login middleware and contains the basic attributes of the users 👇.

class User(UserMixin):
    """用户类"""
    def __init__(self, user):
        self.username = user[1]
        self.password_hash = user[2]
        self.id = user[0]

    def verify_password(self, password):
        """密码验证"""
        if self.password_hash is None:
            return False
        return self.password_hash == password

    def get_id(self):
        """获取用户ID"""
        return self.id

    @staticmethod
    def get(user_id):
        """根据用户ID获取用户实体,为 login_user 方法提供支持"""
        if not user_id:
            return None
        sql = f'select * from users where id = {user_id}'
        try:
            cursor.execute(sql)
            conf.db.commit()
            result = cursor.fetchall()
            for user in result:
                if user[0] == user_id:
                    return User(user)
            return None

        except Exception as e:
            conf.e()
            print(e)

4.4 Upload the applet into the Aliyun server

We configure database information to connect the application to the MySQL database, and then we use docker to arrange them to the server 👇.

import yaml
import os
import pymysql


filePath = os.path.dirname(__file__)
fileNamePath = os.path.split(os.path.realpath(__file__))[0]
yamlPath = os.path.join(fileNamePath, 'config.yaml')
f = open(yamlPath, 'r', encoding='utf-8')
cont = f.read()
x = yaml.load(cont, Loader=yaml.FullLoader)

db = pymysql.connect(
    host=x['DB']['host'],
    user=x['DB']['username'],
    password=str(x['DB']['password']),
    port=x['DB']['port'],
    database=x['DB']['database']
)

Docker can be used to arrange the server 👇. 

FROM python:3.9
ADD . /app
WORKDIR /app
RUN pip install -r requirements.txt
RUN pip3 install cryptography -i https://pypi.tuna.tsinghua.edu.cn/simple
CMD ["python", "app.py"]

 


 

5.Thing Take Long Time to Finish

  • We spent a lot of time learning about the front end and back end knowledge

As the saying goes: All things are difficult before they are easy. Since we had never come into contact with HTML, CSS, Javascript and other technologies, and also forgot the python we learned in the freshman year, we spent a lot of time at the beginning watching relevant videos on platforms like Bilibili and CSDN, reading related blog materials, mastering some basic knowledge and having a general understanding of the technology. And then learn other advanced knowledge as needed during the implementation of the function.

 

  • We ran into a lot of difficulties in programming the logic

In the process of software practice, especially the setting of the logic of the game is relatively difficult. Sometimes there are some errors that need to be modified, and sometimes it takes a lot of time to find the errors.

  • Encountered many difficulties while debugging the server

We used a server we had before, but we didn't know why it couldn't access the IP. We searched a lot of information and made a lot of attempts but couldn't access the IP. Then we bought a new server and still didn't solve the problem.

 

  • Constantly optimizing software takes time

When we finish a version, we find problems that need to be fixed, and then we make suggestions to improve the game interface and the game experience, which sometimes requires rework and takes a lot of time.

 


 

6.GitHub Link and Commit Record  

For convenience, we share the same computer to write most of the codes for convenience thus all of our work has been uploaded to the same github.

https://github.com/fish-Rita/bobing

 


 

7.Program Experience

Actually, we stayed up a few nights and even consumed some kinds of junk food as supply of body energy hhh~ For us, although it was a really hard process, we learned a lot basic and common grammar usages on developing the applets, which also make us realize the vital importance of communication and cooperation with partners, eventually, we achieve a sense of achievement.

 

Great Gain

The level of difficulty in this lab is not friendly for us due to the limitation of time and specialized  master of software development. Luckily, since one of our teammates is more familiar with using flask structure, we use it as a tool to develop web service. Meanwhile, for front end, we know more about how to use html and css language, that we never deal with before, to properly arrange a applet web page and use javascript to judge the results of dices; for back end, we use python to check the information of logging and store the account’s data. Furthermore, we successfully package all the program and deliver it to the Aliyun sever. Despite there are a lot of features we haven't implemented yet, we still propose some plans for out further improvement if we had enough time such as improvements of multiplayer interface’s and optimization of the game experience and set up BGM, etc.

 

 

 

 

...全文
131 回复 打赏 收藏 举报
写回复
回复
切换为时间正序
请发表友善的回复…
发表回复
发帖
FZU-SE-EE308-2022秋

267

社区成员

福州大学 梅努斯国际工程学院 软件工程(2022秋) 教学
软件工程 高校
社区管理员
  • LinQF39
加入社区
帖子事件
编辑了帖子 (查看)
2022-11-19 02:30
编辑了帖子 (查看)
2022-11-18 23:52
创建了帖子
2022-11-18 23:44
社区公告
暂无公告