黄金点游戏开发
黄金点游戏开发
一、设计方案及平台
题目要求
N个同学(N通常大于10),每人写一个0~100之间的有理数 (不包括0或100),交给裁判,裁判算出所有数字的平均值,然后乘以0.618(所谓黄金分割常数),得到G值。提交的数字最靠近G(取绝对值)的同学得到N分,离G最远的同学得到-2分,其他同学得0分。
解题思路
N位同学根据自己的判断填写一个有理数,那么就不能受到别人数字的干扰,也不允许某些人看到他人填写数字,这有失公平。因此,本项目组决定通过账号密码来标识不同的玩家,每当一个玩家输入完成后,自动跳转到登录界面,并且登录成功后能够显示数字输入框,由此输入,最后等到所有玩家都输入成功后,计算平均值和黄金点,给每一个用户返回得分,并记录。
开发平台
Qt、sqlite
Qt设计程序界面快捷便利,而我们需要sqlite用于存储用户的用户名、密码和历史得分。
二、界面设计
| 主界面 | 游戏界面 | |
|---|---|---|
| Qt ui 设计 | ![]() |
![]() |
主界面上显示游戏的名称,每轮的人数以及开始游戏按钮。针对管理员,会有用户管理的选项。
游戏界面中,有用户名、密码、确认密码和点数的输入选项。可以通过用户名输入后的内容,与后端sqlite的数据库中存储的用户名进行比对。倘若该用户已注册,则不会弹出确认密码选项,直接输入密码,和点数,当密码有效时,便可以通过确认案件直接进入下一位玩家的输入选项;若该用户未注册,则自动弹出确认密码选项,用户可以当场注册并输入点数,用户注册的用户名和密码的转码都会保存入数据库中方便下一次的游戏。
三、核心代码
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QMessageBox>
#include <QSqlDatabase>
#include <QSqlQuery>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
db.setDatabaseName("user.db");
if(!db.open())
{
QMessageBox::critical(0,"Cannot open database","Unable to establish a database connection.",QMessageBox::Cancel);
throw("用户数据库都创建不了,不用继续了");
}
QSqlQuery query;
query.exec("CREATE TABLE USERS (USERNAME VARCHAR(256),PASSWD_SHA256 CHAR(64));");
gameInputDialog=new GameInputDialog(this);
QObject::connect(gameInputDialog,&GameInputDialog::checkUsernameExist,this,&MainWindow::response_to_checkUsernameExist);
QObject::connect(gameInputDialog,&GameInputDialog::checkPasswdCorrect,this,&MainWindow::response_to_checkPasswdCorrect);
QObject::connect(gameInputDialog,&GameInputDialog::registerUser,this,&MainWindow::response_to_registerUser);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_gameStartButton_clicked()
{
qint8 personCount=ui->personCountEdit->value();
for(int i=1;i<=personCount;++i){
gameInputDialog->reset(i);
gameInputDialog->exec();
}
}
void MainWindow::response_to_registerUser(){
QSqlQuery query;
// query.exec(QString("INSERT INTO users VALUES (321,NULL);"));
query.exec(QString("INSERT INTO USERS VALUES (\'%1\',\'%2\');").arg(gameInputDialog->getUsername()).arg(gameInputDialog->getPasswdSHA256()));
}
void MainWindow::response_to_checkPasswdCorrect(){
QSqlQuery query;
query.exec(QString("SELECT * FROM USERS WHERE USERNAME=\"%1\" AND PASSWD_SHA256=\"%2\";").arg(gameInputDialog->getUsername()).arg(gameInputDialog->getPasswdSHA256()));
gameInputDialog->setPasswdCorrect(query.next());
}
void MainWindow::response_to_checkUsernameExist(){
QSqlQuery query;
query.exec(QString("SELECT * FROM USERS WHERE USERNAME=\"%1\"").arg(gameInputDialog->getUsername()));
gameInputDialog->setUsernameExist(query.next());
}
gameinputdialog.cpp
#include "gameinputdialog.h"
#include "ui_gameinputdialog.h"
#include <QCryptographicHash>
#include <QMessageBox>
#include <QDebug>
GameInputDialog::GameInputDialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::GameInputDialog)
{
ui->setupUi(this);
}
GameInputDialog::~GameInputDialog()
{
delete ui;
}
QString GameInputDialog::getUsername() const{
return ui->usernameEdit->text();
}
QString GameInputDialog::getPasswdSHA256() const{
QString passwd = ui->passwdEdit->text();
return QCryptographicHash::hash(passwd.toUtf8(),QCryptographicHash::Sha256).toHex();
}
double GameInputDialog::getPoint() const{
return ui->pointEdit->value();
}
void GameInputDialog::reset(int index){
this->setWindowTitle(QString("第%1位").arg(index));
ui->usernameEdit->clear();
set(USERNAME);
}
void GameInputDialog::set(Status status){
this->status=status;
switch(status){
case USERNAME:
ui->usernameLabel->setText("USERNAME");
break;
case CREATE_ACCOUNT:
ui->usernameLabel->setText("CREATE_ACCOUNT");
break;
case POINT:
ui->usernameLabel->setText("POINT");
break;
}
switch(status){
case USERNAME:
ui->passwdEdit->clear();
ui->confirmPasswdEdit->clear();
ui->pointEdit->clear();
ui->userNotFoundWarning->setVisible(false);
ui->passwdLabel->setVisible(false);
ui->passwdEdit->setVisible(false);
ui->passwdIncorrectWarning->setVisible(false);
ui->confirmPasswdLabel->setVisible(false);
ui->confirmPasswdEdit->setVisible(false);
ui->passwdConfirmWarning->setVisible(false);
ui->pointLabel->setVisible(false);
ui->pointEdit->setVisible(false);
break;
case CREATE_ACCOUNT:
ui->passwdEdit->clear();
ui->confirmPasswdEdit->clear();
ui->userNotFoundWarning->setVisible(false);
ui->passwdLabel->setVisible(true);
ui->passwdEdit->setVisible(true);
ui->passwdIncorrectWarning->setVisible(false);
ui->confirmPasswdLabel->setVisible(true);
ui->confirmPasswdEdit->setVisible(true);
ui->passwdConfirmWarning->setVisible(false);
ui->pointLabel->setVisible(false);
ui->pointEdit->setVisible(false);
break;
case POINT:
ui->passwdEdit->clear();
ui->pointEdit->clear();
ui->userNotFoundWarning->setVisible(false);
ui->passwdLabel->setVisible(true);
ui->passwdEdit->setVisible(true);
ui->passwdIncorrectWarning->setVisible(false);
ui->confirmPasswdLabel->setVisible(false);
ui->confirmPasswdEdit->setVisible(false);
ui->passwdConfirmWarning->setVisible(false);
ui->pointLabel->setVisible(true);
ui->pointEdit->setVisible(true);
break;
}
this->resize(this->sizeHint());
}
void GameInputDialog::setUsernameExist(bool Bool){
if(Bool){
set(POINT);
}else{
set(CREATE_ACCOUNT);
ui->userNotFoundWarning->setVisible(true);
}
}
void GameInputDialog::setPasswdCorrect(bool Bool){
if(Bool){
accept();
}else{
ui->passwdIncorrectWarning->setVisible(true);
}
}
void GameInputDialog::setRegisterd(){
QString username=ui->usernameEdit->text();
QString passwd=ui->passwdEdit->text();
set(POINT);
ui->usernameEdit->setText(username);
ui->passwdEdit->setText(passwd);
}
void GameInputDialog::on_usernameEdit_editingFinished()
{
emit checkUsernameExist();
}
void GameInputDialog::on_acceptButton_clicked()
{
switch(status){
case USERNAME:
break;
case CREATE_ACCOUNT:
if(!ui->passwdEdit->text().compare(ui->confirmPasswdEdit->text())){
emit registerUser();
}
break;
case POINT:
if(!ui->confirmPasswdEdit->text().compare(ui->passwdEdit->text()))
emit(checkPasswdCorrect());
break;
}
}
void GameInputDialog::on_confirmPasswdEdit_textEdited(const QString &arg1)
{
if(arg1.compare(ui->passwdEdit->text())){
ui->passwdConfirmWarning->setVisible(true);
}else{
ui->passwdConfirmWarning->setVisible(false);
}
}
void GameInputDialog::on_passwdEdit_textEdited(const QString &arg1)
{
switch(status){
case CREATE_ACCOUNT:
if(arg1.compare(ui->passwdEdit->text())){
ui->passwdConfirmWarning->setVisible(true);
}else{
ui->passwdConfirmWarning->setVisible(false);
}
break;
case POINT:
case USERNAME:
break;
}
}
四、测试与不足
测试的时候能弹出界面,但是操作时报了好多错,还在修改中。
五、改进与迭代
之后我们会针对前面测试中出现的错误进行修复。当第一版软件完成时,我们后续会优化图形界面,选择不同的编程语言实现;或者更进一步的通过jsp servlet通信完成web编程。



浙公网安备 33010602011771号