对原有项目的改进
首先,本次版本在原有基础上增加了多轮游戏累计积分功能,这样可以让参与者们经过多轮游戏的角逐在深思熟虑的情况下决定胜负,而非仅仅可能单靠运气的一轮。
同时,我们为游戏增加了历史游戏结果查询的功能,参与者可以查询历史记录,观看每一轮的游戏计算结果、游戏获胜数字、游戏失败数字,并以此作为依据来判断此后每轮的走势。
而后,我们增加了一个AI参与游戏,AI会自动根据前面几轮的游戏结果来对本轮游戏获胜数字进行预测。
最后,在功能实现上,修改了部分游戏规则,我们在分数设置上进行了更加灵活的改进,将AI作为最后一名玩家加入游戏,并对相应算法进行了优化。
效果展示
多轮游戏累计分数:
历史得分记录显示
AI进行游戏效果展示
如图,AI在经过前两轮后陷入劣势,分数为-4,而后立马根据前两轮结果进行分析,给出了新的预测数据。
在经过预测后,AI获得的第三轮的胜利
实现代码
每轮游戏结果计算及累加:在原有算法的基础上,增加了计数器timer记录游戏轮数,并且用三个数组分别记录游戏结果、获胜数字及失败数字,并将之前较芜杂的代码进行了精简。
void CnewgoldDlg::OnBnClickedButtonbegin()
{
// TODO: 在此添加控件通知处理程序代码
int iCount = m_list.GetItemCount();
for (int i = 0; i < iCount; i++)
{
CString begin;
begin.Format(_T("%d"), 0);
m_list.SetItemText(i, 3, begin);
}
double sum = 0;
for (int i = 0; i < iCount; i++)
{
sum += _ttof(m_list.GetItemText(i, 1));//将CString类型转换为double类型
sum += _ttof(m_list.GetItemText(i, 2));
}
CString avg;
avg.Format(_T("%f"), sum / iCount * 0.618);//将double类型转换为CString,用Format()
double davg;
davg = _ttof(avg);
double max = fabs(_ttof(m_list.GetItemText(0, 1)) - davg), min = fabs(_ttof(m_list.GetItemText(0, 1)) - davg);
int flagmax = 0, flagmin = 0;
int flagmaxcol = 0, flagmincol = 0;
int ismax = 0, ismin = 0;
number[timer] = davg;
winer[timer] = _ttof(m_list.GetItemText(0, 1));
loser[timer] = _ttof(m_list.GetItemText(0, 1));//初始化,设置为第一个人的数
for (int i = 0; i < iCount; i++)
{
if (max < fabs(_ttof(m_list.GetItemText(i, 1)) - davg))
{
max = fabs(_ttof(m_list.GetItemText(i, 1)) - davg);
loser[timer] = _ttof(m_list.GetItemText(i, 1));//记录失败者
flagmax = i;
flagmaxcol = 1;
}
if (min > fabs(_ttof(m_list.GetItemText(i, 1)) - davg))
{
min = fabs(_ttof(m_list.GetItemText(i, 1)) - davg);
winer[timer] = _ttof(m_list.GetItemText(i, 1));//记录胜利者
flagmin = i;
flagmincol = 1;
}
}
for (int i = 0; i < iCount; i++)
{
if (max < fabs(_ttof(m_list.GetItemText(i, 2)) - davg))
{
max = fabs(_ttof(m_list.GetItemText(i, 2)) - davg);
loser[timer] = _ttof(m_list.GetItemText(i, 2));//记录失败者
flagmax = i;
flagmaxcol = 2;
}
if (min > fabs(_ttof(m_list.GetItemText(i, 2)) - davg))
{
min = fabs(_ttof(m_list.GetItemText(i, 2)) - davg);
winer[timer] = _ttof(m_list.GetItemText(i, 2));//记录胜利者
flagmin = i;
flagmincol = 2;
}
}
CString score;
for (int i = 0; i < iCount; i++)//分数计算
{
if (fabs(_ttof(m_list.GetItemText(i, 1)) - davg) == fabs(_ttof(m_list.GetItemText(flagmax, flagmaxcol)) - davg)||
fabs(_ttof(m_list.GetItemText(i, 2)) - davg) == fabs(_ttof(m_list.GetItemText(flagmax, flagmaxcol)) - davg))
{
sco[i] -= 2;
}
if (fabs(_ttof(m_list.GetItemText(i, 1)) - davg) == fabs(_ttof(m_list.GetItemText(flagmin, flagmincol)) - davg)||
fabs(_ttof(m_list.GetItemText(i, 2)) - davg) == fabs(_ttof(m_list.GetItemText(flagmin, flagmincol)) - davg))
{
sco[i] += iCount;
}
}
for (int i = 0; i < iCount; i++) {
score.Format(_T("%d"), sco[i]);
m_list.SetItemText(i, 3, score);
}
timer++;
}
历史记录显示:弹出新的窗口,并将每轮结果以统计表的形式进行显示。
BOOL sta::OnInitDialog()
{
CDialogEx::OnInitDialog();
sta_list.InsertColumn(0, _T("游戏轮数"), 0, 150);
sta_list.InsertColumn(1, _T("本轮结果"), 0, 150);
sta_list.InsertColumn(2, _T("获胜数字"), 0, 150);
sta_list.InsertColumn(3, _T("失败数字"), 0, 150);
// TODO: 在此添加额外的初始化
CString score;
for (int i = 0;i < timer;i++) {
score.Format(_T(" %d"), i+1);
sta_list.InsertItem(i, score);
score.Format(_T(" %f"), number[i]);
sta_list.SetItemText(i, 1, score);
score.Format(_T(" %f"), winer[i]);
sta_list.SetItemText(i, 2, score);
score.Format(_T(" %f"), loser[i]);
sta_list.SetItemText(i, 3, score);
}
return TRUE; // return TRUE unless you set the focus to a control
// 异常: OCX 属性页应返回 FALSE
}
AI算法编写:设置预测项和干扰项,以前一轮结果来设置干扰项来扰动结果,根据前两轮结果及自己输入的干扰项来设置预测项从而保证胜利。
void CnewgoldDlg::OnBnClickedButtonAi()//AI参加按钮
{
// TODO: 在此添加控件通知处理程序代码
double forecast, disturb;
CString AI("AI");
CString gold;
if (timer == 0)
{
int cout = m_list.GetItemCount();
m_list.InsertItem(cout, AI);
forecast = 30.9;//如果所有人写随机数字,那么数字的平均值就是50,50乘0.618为30.9
disturb = 30.9;
gold.Format(_T("%f"), forecast);
m_list.SetItemText(cout, 1, gold);
gold.Format(_T("%f"), disturb);
m_list.SetItemText(cout, 2, gold);
}
else if (timer == 1)
{
int cout = m_list.GetItemCount();
forecast = 30.9;
disturb = 30.9;
gold.Format(_T("%f"), forecast);
m_list.SetItemText(cout-1, 1, gold);
gold.Format(_T("%f"), disturb);
m_list.SetItemText(cout-1, 2, gold);
}
else
{
int cout = m_list.GetItemCount();
disturb = number[timer-1]*0.618;//设置干扰数为上一轮黄金点的0.618
double nextpoint = (number[timer - 1] * number[timer - 1]) / number[timer - 2];//根据上两轮确定这轮黄金点的趋势
forecast = nextpoint + (disturb-nextpoint) / 8 * 0.618;//加入干扰项考虑
gold.Format(_T("%f"), forecast);
m_list.SetItemText(cout-1, 1, gold);
gold.Format(_T("%f"), disturb);
m_list.SetItemText(cout-1, 2, gold);
}
}
小结
经过几次改进后,我们的黄金点游戏预期功能已经基本实现,从原本简单的单轮单数字黄金点游戏一步步改进成了如今的累计轮数双数字的黄金点游戏,并且加入了AI来为玩家们增加游戏难度及游戏乐趣。