1、能够知道所有的获胜组合; 2、建立和使用获胜表; 3、设定获胜的分数; 4、使电脑具有攻击和防守的能力; 一、求五子棋的获胜组合 在一场五子棋的游戏中,计算机必须要知道有那些的获胜组合,因此我们必须求得获胜组合的总数。我们假定当前的棋盘为10*10。 (1)计算水平方向的获胜组合数,每一列的获胜组合是:6,共10列,所以水平方向的获胜组合数为:6*10=60 (2)计算垂直方向的获胜组合总数,每一行的获胜组合是:6,共10行,则垂直方向的获胜组合数为:6*10=60 (3)计算正对角线方向的获胜组合总数,正对角线上的获胜组合总数为6+(5+4+3+2+1)*2=36 (4)计算反对角线方向的获胜组合总数,反对角线上的获胜组合总数为6+(5+4+3+2+1)*2=36 ,这样所有的获胜组合数为:60+60+36+36=192 二、建立和使用获胜表 我们已经计算出了一个10*10的五子棋盘会有192种获胜方式,这样我们可以利用数组建立获胜表,获胜表的主要作用是:1,判断当前的获胜方式是否有效;2,判断当前的获胜方式中到底有多少子落入该获胜组合中。详细的使用您将在后面的程序中可以看出。 三,分数的设定 在游戏中为了让计算机能够决定下一步最佳的走法,必须先计算出计算机下到棋盘上任一空格的分数,而其中最高分数便是计算机下一步的最佳走法。 原理:我们判定当前讨论的空格与当前讨论的点有几种获胜的方式,有几种该空格就加几分。这种原理初听起来似乎是无法入手,没关系,当您了解我们后面的程序后您就会明白这种决策原理了。 这种决策有一些缺陷,因为如果只根据这个模型设计,就有可能出现电脑或玩家有三个子连成一线的时候,计算机却判断不出,它认为其他某些空格是当前的获胜的最佳位置而不去攻击或防守。没关系我们完全可以通过一个加强算法来改变当前的分值情况,也就是说当电脑或玩家有三个子或四个子连成一线时,我们通过加强算法将当前与三个子或四个子有关的空格的分值提高,从而可以弥补这一缺憾。 四、攻击与防守 以上的方式,事实上计算机只是计算出了最佳的攻击位置,为了防守我们还应计算当前玩家的最佳的攻击位置。这样有什么用呢?道理很简单,如果玩家最佳攻击位置的分数大于计算机最佳攻击位置上的分数,那么计算机就将下一步的棋子摆在玩家的最佳攻击位上以阻止玩家的进攻,否则计算机便将棋子下在自己的最佳攻击位置上进行攻击。 事实上,这个AI构想是很强大的如果你不是很厉害的五子棋高手的话,可能很快会被计算机打败。我在联众上可是中级棋手啊,跟这种构想打的时候胜率也不是很高。 使用vb.net编写五子棋 一、编写前的准备: 1、用计算机的思想描述整个下棋的过程 考虑步骤: (1)为了简便我们可以先让电脑先走第一步棋,电脑每走一步就会封掉许多玩家的获胜可能情况。 (2)当玩家走棋的时候我们首先应该考虑玩家走棋的合法性。 (3)如果合法,那么玩家也会封掉许多电脑的获胜的可能情况。 (4)电脑的思考路径:首先判断当前玩家和电脑的所有获胜组合是否需要进行加强赋值,
是进行加强赋值,否则进行普通的赋值。 (5)比较当前玩家和电脑谁的分值最大。将分值最大的点作为电脑的下一步走法。 2、利用vb.net窗体和图形工具建立五子棋的棋盘界面 (1)添加一个picturebox控件 作用:使用picturebox控件绘制棋子和棋盘 (2)添加一个label控件 作用:显示当前的获胜标志,也就是当某一方获胜或和棋时显示此标签。 (3)添加一个mainmenu控件 作用:控制游戏的开始或结束 (4)添加一个mediaplay组件 作用:使程序可以播放音乐。 3、设置整体框价 我们采取10*10的棋盘,为主要的平台。利用数组定义整个棋盘桌面,利用数组定义获胜组合以及获胜标志等。 二,声明全局数组和变量 定义虚拟桌面: Dim table(9, 9) As Integer 定义当前玩家桌面空格的分数: Dim pscore(9, 9) As Integer 定义当前电脑桌面空格的分数: Dim cscore(9, 9) As Integer 定义玩家的获胜组合: Dim pwin(9, 9, 191) As Boolean 定义电脑的获胜组合: Dim cwin(9, 9, 191) As Boolean 定义玩家的获胜组合标志: Dim pflag(191) As Boolean 定义电脑的获胜组合标志:
Dim cflag(191) As Boolean 定义游戏有效标志: Dim theplayflag As Boolean 三、初始化游戏 '*****************************************************************************
'** 模块名称: initplayenvironment
'**
'** 描述: 此函数主要功能如下:
'** 1. 设置背景音乐。
'** 2. 设置游戏状态有效。
'** 3. 初始化游戏状态标签。
'** 4. 直接指定电脑的第一步走法。
'** 5. 初始化基本得分桌面。
'** 6. 电脑和玩家获胜标志初始化。
'** 7. 初始化所有获胜组合。
'** 8. 重新设定玩家的获胜标志。
'**
'*****************************************************************************
Sub initplayenvironment()
player.FileName = ".\music\zhyu01.mid"
player.Play()
theplayflag = True
'游戏有效
Label1.Visible = False
'游戏状态标签不显示
PictureBox1.Refresh()
'清空picturebox1的内容
yuandian(130, 130)
'调用绘图函数绘制当前电脑先走的位置
Dim i, j, m, n As Integer
For i = 0 To 9
For j = 0 To 9
table(i, j) = 0
Next
Next
'桌面初始化
For i = 0 To 191
pflag(i) = True
cflag(i) = True
Next
'获胜标志初始化
table(4, 4) = 1
'由于我们设定电脑先手,并下了4,4位所以将其值设为1
''' ******** 初始化获胜组合 ********
n = 0
For i = 0 To 9
For j = 0 To 5
For m = 0 To 4
pwin(j + m, i, n) = True
cwin(j + m, i, n) = True
Next
n = n + 1
Next
Next
For i = 0 To 9
For j = 0 To 5
For m = 0 To 4
pwin(i, j + m, n) = True
cwin(i, j + m, n) = True
Next
n = n + 1
Next
Next
For i = 0 To 5
For j = 0 To 5
For m = 0 To 4
pwin(j + m, i + m, n) = True
cwin(j + m, i + m, n) = True
Next
n = n + 1
Next
Next
For i = 0 To 5
For j = 9 To 4 Step -1
For m = 0 To 4
pwin(j - m, i + m, n) = True
cwin(j - m, i + m, n) = True
Next
n = n + 1
Next
Next
''' ******** 初始化获胜组合结束 ********
For i = 0 To 191
If pwin(4, 4, i) = True Then
pflag(i) = False
End If
Next
'由于电脑已下了4,4位所以我们需要重新设定玩家的获胜标志
End Sub
四,处理鼠标事件 '*****************************************************************************
'** 模块名称: themousedown
'**
'** 描述: 此函数主要实行以下功能:
'** 1. 判定当前游戏标志是否有效。
'** 2. 将实际坐标转化成虚拟坐标。
'** 3. 绘制玩家的棋子。
'** 4. 执行检查获胜函数。
'** 5. 执行电脑算法函数。
'**
'*****************************************************************************
Sub themousedown(ByVal x As Integer, ByVal y As Integer)
If theplayflag = False Then
Exit Sub
End If
'检查游戏状态是否有效
Dim i, j As Integer
Dim zhx, zhy As Integer
zhx = Int((x - 10) / 30)
zhy = Int((y - 10) / 30)
For i = 0 To 9
For j = 0 To 9
If table(zhx, zhy) >0 Then
Exit Sub
End If
Next
Next
'检查当前鼠标点击的格子是否有效
Dim mycolor As Color
Dim g As System.Drawing.Graphics
g = PictureBox1.CreateGraphics
mycolor = Color.White
Dim brush1 As System.Drawing.Brush = New SolidBrush(mycolor)
g.FillEllipse(brush1, zhx * 30 + 10, zhy * 30 + 10, 30, 30)
'绘制玩家的棋子
table(zhx, zhy) = 2
For i = 0 To 191
If cwin(zhx, zhy, i) = True Then
cflag(i) = False
End If
Next
'重设电脑的获胜标志
checkwin()
'检查当前玩家是否获胜
diannao()
'调用电脑算法
End Sub 五、获胜检查算法。 '*****************************************************************************
'** 模块名称: checkwin
'**
'** 描述: 此模块执行以下功能:
'** 1. 检查是否和棋。
'** 2. 检查电脑是否获胜。
'** 3. 检查玩家是否获胜。
'**
'*****************************************************************************
Sub checkwin()
Dim i, j, k, m, n As Integer
Dim ca As Integer
Dim pa As Integer
Dim cnormal As Integer = 0
For i = 0 To 191
If cflag(i) = False Then
cnormal = cnormal + 1
End If
Next
If cnormal = 190 Then
Label1.Visible = True
Label1.Text = "和棋,请重新开始!"
PictureBox1.Refresh()
theplayflag = False
Exit Sub
End If
'设定和棋规则
For i = 0 To 191
If cflag(i) = True Then
ca = 0
For j = 0 To 9
For k = 0 To 9
If table(j, k) = 1 Then
If cwin(j, k, i) = True Then
ca = ca + 1
End If
End If
Next
Next
If ca = 5 Then
Label1.Visible = True
Label1.Text = "电脑获胜,请重新开始"
PictureBox1.Refresh()
theplayflag = False
Exit Sub
End If
End If
Next
'检查电脑是否获胜
For i = 0 To 191
If pflag(i) = True Then
pa = 0
For j = 0 To 9
For k = 0 To 9
If table(j, k) = 2 Then
If pwin(j, k, i) = True Then
pa = pa + 1
End If
End If
Next
Next
If pa = 5 Then
Label1.Visible = True
Label1.Text = "玩家获胜,请重新开始"
PictureBox1.Refresh()
theplayflag = False
Exit Sub
End If
End If
Next
'检查玩家是否获胜
End Sub 六、电脑算法 '*****************************************************************************
'** 模块名称: diannao
'**
'** 描述: 此程序主要执行以下功能:
'** 1. 初始化赋值系统。
'** 2. 赋值加强算法。
'** 3. 计算电脑和玩家的最佳攻击位。
'** 4. 比较电脑和玩家的最佳攻击位并决定电脑的最佳策略。
'** 5. 执行检查获胜函数。
'**
'***************************************************************************** Sub diannao()
Dim i, j, k, m, n As Integer
Dim dc As Integer
Dim cab As Integer
Dim pab As Integer
For i = 0 To 9
For j = 0 To 9
pscore(i, j) = 0
cscore(i, j) = 0
Next
Next
'初始化赋值数组
''' ******** 电脑加强算法 ********
For i = 0 To 191
If cflag(i) = True Then
cab = 0
For j = 0 To 9
For k = 0 To 9
If table(j, k) = 1 Then
If cwin(j, k, i) = True Then
cab = cab + 1
End If
End If
Next
Next
Select Case cab
Case 3
For m = 0 To 9
For n = 0 To 9
If table(m, n) = 0 Then
If cwin(m, n, i) = True Then
cscore(m, n) = cscore(m, n) + 5
End If
End If
Next
Next
Case 4
For m = 0 To 9
For n = 0 To 9
If table(m, n) = 0 Then
If cwin(m, n, i) = True Then
yuandian(m * 30 + 10, n * 30 + 10)
table(m, n) = 1
For dc = 0 To 191
If pwin(m, n, dc) = True Then
pflag(dc) = False
checkwin()
Exit Sub
End If
Next
End If
End If
Next
Next
End Select
End If
Next
For i = 0 To 191
If pflag(i) = True Then
pab = 0
For j = 0 To 9
For k = 0 To 9
If table(j, k) = 2 Then
If pwin(j, k, i) = True Then
pab = pab + 1
End If
End If
Next
Next
Select Case pab
Case 3
For m = 0 To 9
For n = 0 To 9
If table(m, n) = 0 Then
If pwin(m, n, i) = True Then
pscore(m, n) = pscore(m, n) + 30
End If
End If
Next
Next
Case 4
For m = 0 To 9
For n = 0 To 9
If table(m, n) = 0 Then
If pwin(m, n, i) = True Then
yuandian(m * 30 + 10, n * 30 + 10)
table(m, n) = 1
For dc = 0 To 191
If pwin(m, n, dc) = True Then
pflag(dc) = False
checkwin()
Exit Sub
End If
Next
End If
End If
Next
Next
End Select
End If
Next
''' ******** 电脑加强算法结束 ******** ' ******** 赋值系统 ********
For i = 0 To 191
If cflag(i) = True Then
For j = 0 To 9
For k = 0 To 9
If table(j, k) = 0 Then
If cwin(j, k, i) = True Then
For m = 0 To 9
For n = 0 To 9
If table(m, n) = 1 Then
If cwin(m, n, i) = True Then
cscore(j, k) = cscore(j, k) + 1
End If
End If
Next
Next
End If
End If
Next
Next
End If
Next
For i = 0 To 191
If pflag(i) = True Then
For j = 0 To 9
For k = 0 To 9
If table(j, k) = 0 Then
If pwin(j, k, i) = True Then
For m = 0 To 9
For n = 0 To 9
If table(m, n) = 2 Then
If pwin(m, n, i) = True Then
pscore(j, k) = pscore(j, k) + 1
End If
End If
Next
Next
End If
End If
Next
Next
End If
Next
''' ******** 赋值系统结束 ********
''' ******** 分值比较算法 ********
Dim a, b, c, d As Integer
Dim cs As Integer = 0
Dim ps As Integer = 0
For i = 0 To 9
For j = 0 To 9
If cscore(i, j) >cs Then
cs = cscore(i, j)
a = i
b = j
End If
Next
Next
For i = 0 To 9
For j = 0 To 9
If pscore(i, j) >ps Then
ps = pscore(i, j)
c = i
d = j
End If
Next
Next
If cs >ps Then
yuandian(a * 30 + 10, b * 30 + 10)
table(a, b) = 1
For i = 0 To 191
If pwin(a, b, i) = True Then
pflag(i) = False
End If
Next
Else
yuandian(c * 30 + 10, d * 30 + 10)
table(c, d) = 1
For i = 0 To 191
If pwin(c, d, i) = True Then
pflag(i) = False
End If
Next
End If
''' ******** 分值比较算法结束 ********
checkwin()
End Sub 七、绘制棋子 '*****************************************************************************
'** 模块名称: yuandian
'**
'** 描述: 此函数主要进行电脑棋子的绘制。
'**
'***************************************************************************** Sub yuandian(ByVal x As Integer, ByVal y As Integer)
Dim mycolor As Color
Dim g As System.Drawing.Graphics
g = PictureBox1.CreateGraphics
Dim zhx, zhy As Integer
zhx = Int((x - 10) / 30)
zhy = Int((y - 10) / 30)
mycolor = Color.Black
Dim brush1 As System.Drawing.Brush = New SolidBrush(mycolor)
g.FillEllipse(brush1, zhx * 30 + 10, zhy * 30 + 10, 30, 30)
End Sub
#include<iostream>#include<cstdlib>
using namespace std
class CHESS
{
public:
CHESS()
void setStep(bool&ipjudge)//双人对战轮流走棋函数
void setStepC(bool&ipjudge)//人机对战走棋函数
void coutChess()//输出棋盘
void coutPW()//输出权值表
bool getTurn(){flag=!flagreturn flag}//轮流走棋控制函数
void flushChess()//刷新棋盘信息函数
void judgeWin()//判断是否赢棋函数
void winer()//赢家输出函数
int getAns(){return result}//返回结果(赢家判断)
static int count//走棋步数变量
private:
bool flag//轮流走棋判断变量
int PW[16][16],tPW[4]//权值变量,最高权值变量
int result,num[2]//结果(赢家判断),玩家输入棋子坐标判断
char inPut[2],temp[2]//玩家输入数据,转换暂存数据
char CBoard[16][16]//棋盘数据
int judgeAWin(int a,int b)//判断是否A为赢家函数
int judgeBWin(int a,int b)//判断是否B为赢家函数
void cSetStep()//电脑走棋函数
void setPower()//初始化权值函数
int adddepth(int depth)//填充权值函数
void judgePw(int x,int y,int direction,int depth,char test)//棋子判断[x坐标,y坐标,方向(顺时针0-无,1-左,2-左上,3-上,4-右上),深度(depth),标识符(A/B)]
void getFinalPw()
//权值判断函数
}
int CHESS::count=0
void VsComputer() //人机对战
void VsPlayer()//双人对战
int main()
{
int choose
CHESS newP
do
{
choose=0
system("cls")
cout<<" 欢乐五子棋"<<endl<<endl
cout<<"请选择:"<<endl<<endl
cout<<"1:人机对战模式"<<endl<<endl
cout<<"2:双人对战模式"<<endl<<endl
cout<<"3:退出游戏"<<endl<<endl<<endl
cout<<"**************"<<endl
cout<<"**************"<<endl<<endl<<endl<<endl
cout<<"请输入你的选择:"
cin>>choose
if(choose==2)
VsPlayer()
else if(choose==1)
VsComputer()
else if(choose==3)
exit(0)
else
{
cout<<"输入错误,请重新输入!"<<endl
system("pause")
}
}while(choose!=3)
return 0
}
void VsComputer()
{
bool ipjudge
CHESS newP
do
{
newP.coutChess()
newP.setStepC(ipjudge)//人机对战函数
if(!ipjudge)
continue
if(!newP.getTurn())
newP.flushChess()
newP.coutChess()
newP.judgeWin()
CHESS::count++
}while(newP.getAns()==0&&CHESS::count<256)
newP.winer()
}
void CHESS::setStepC(bool&ipjudge)
{
int i
if(flag)
{
cout<<"棋手走棋:"
cin>>inPut
for(i=0i<=1i++)
if(inPut[i]<'0'||(inPut[i]>'9'&&inPut[i]<'O')||(inPut[i]>'F'&&inPut[i]<'O')||inPut[i]>'f')
{
ipjudge=false
cout<<"输入越界,请重新输入!"
system("pause")
break
}
}
else
cSetStep()//轮到电脑走棋
}
void CHESS::cSetStep()
{
int i,j,depth=0
setPower()
for(i=0i<16i++)
{
for(j=0j<16j++)
{
if(CBoard[i][j]=='+')//优化:排除周围全是+的情况
{
if(CBoard[i-1][j]=='O'||CBoard[i-1][j-1]=='O'||CBoard[i][j-1]=='O'||CBoard[i+1][j-1]=='O'||CBoard[i+1][j]=='O'||CBoard[i+1][j+1]=='O'||CBoard[i][j+1]=='O'||CBoard[i-1][j+1]=='O')
{
judgePw(i,j,0,depth,'O')
judgePw(i,j,0,depth,'X')
}
else if(CBoard[i-1][j]=='X'||CBoard[i-1][j-1]=='X'||CBoard[i][j-1]=='X'||CBoard[i+1][j-1]=='X'||CBoard[i+1][j]=='X'||CBoard[i+1][j+1]=='X'||CBoard[i][j+1]=='X'||CBoard[i-1][j+1]=='X')
{
judgePw(i,j,0,depth,'O')
judgePw(i,j,0,depth,'X')
}
}
}
}
getFinalPw()
//coutPW()
//system("pause")
if(tPW[0]>0)
CBoard[tPW[1]][tPW[2]]='X'
/*else if(tPW[0]>0&&tPW[3]>1)
{
for(i=0i<16i++)
{
for(j=0j<16j++)
{
if(tPW[0]==PW[i][j])
if()
}
}
}*/
else
{
cout<<"权值函数错误!"
system("pause")
exit(1)
}
}
void CHESS::judgePw(int x,int y,int direction,int depth,char test)
{
if(depth>=0&&depth<4)
{
if(direction==1)//左方
{
if(CBoard[x-depth-1][y]==test)
judgePw(x,y,1,depth+1,test)
else
PW[x][y]+=adddepth(depth)
}
else if(direction==2)//左上方
{
if(CBoard[x-depth-1][y-depth-1]==test)
judgePw(x,y,2,depth+1,test)
else
PW[x][y]+=adddepth(depth)
}
else if(direction==3)//正上方
{
if(CBoard[x][y-depth-1]==test)
judgePw(x,y,3,depth+1,test)
else
PW[x][y]+=adddepth(depth)
}
else if(direction==4)//右上方
{
if(CBoard[x+depth+1][y-depth-1]==test)
judgePw(x,y,4,depth+1,test)
else
PW[x][y]+=adddepth(depth)
}
else if(direction==5)//右方
{
if(CBoard[x+depth+1][y]==test)
judgePw(x,y,5,depth+1,test)
else
PW[x][y]+=adddepth(depth)
}
else if(direction==6)//右下方
{
if(CBoard[x+depth+1][y+depth+1]==test)
judgePw(x,y,6,depth+1,test)
else
PW[x][y]+=adddepth(depth)
}
else if(direction==7)//正下方
{
if(CBoard[x][y+depth+1]==test)
judgePw(x,y,7,depth+1,test)
else
PW[x][y]+=adddepth(depth)
}
else if(direction==8)//左下方
{
if(CBoard[x-depth-1][y+depth+1]==test)
judgePw(x,y,6,depth+1,test)
else
PW[x][y]+=adddepth(depth)
}
else if(direction==0)
{
if(CBoard[x-depth-1][y]==test)//左方
judgePw(x,y,1,depth+1,test)
if(CBoard[x-depth-1][y-depth-1]==test)//左上方
judgePw(x,y,2,depth+1,test)
if(CBoard[x][y-depth-1]==test)//正上方
judgePw(x,y,3,depth+1,test)
if(CBoard[x+depth+1][y-depth-1]==test)//右上方
judgePw(x,y,4,depth+1,test)
if(CBoard[x+depth+1][y]==test)//右方
judgePw(x,y,5,depth+1,test)
if(CBoard[x+depth+1][y+depth+1]==test)//右下方
judgePw(x,y,6,depth+1,test)
if(CBoard[x][y+depth+1]==test)//正下方
judgePw(x,y,7,depth+1,test)
if(CBoard[x-depth-1][y+depth+1]==test)//左下方
judgePw(x,y,6,depth+1,test)
}
}
else if(depth==4)
PW[x][y]+=adddepth(depth)
else
{
cout<<"深度函数出错!"
system("pause")
exit(1)
}
}
int CHESS::adddepth(int depth)
{
switch(depth)
{
case 0:return 0break
case 1:return 1break
case 2:return 2break
case 3:return 4break
case 4:return 6break
default:
{
cout<<"深度函数错误!"
system("pause")
exit(1)
}
}
}
void CHESS::getFinalPw()
{
int i,j
for(i=0i<=15i++)
for(j=0j<=15j++)
{
if(PW[i][j]>tPW[0])
{
tPW[0]=PW[i][j]
tPW[1]=i
tPW[2]=j
tPW[3]=1
}
else if(PW[i][j]==tPW[0]&&PW[i][j]!=0)
tPW[3]+=1
}
}
////////////////////////////////////////////////////////////////////////
//双人对战
////////////////////////////////////////////////////////////////////////
void VsPlayer()
{
bool ipjudge
CHESS newP
do
{
newP.coutChess()
newP.setStep(ipjudge)
if(!ipjudge)
continue
newP.getTurn()
newP.flushChess()
newP.coutChess()
newP.judgeWin()
CHESS::count++
}while(newP.getAns()==0&&CHESS::count<256)
newP.winer()
}
void CHESS::winer()
{
if(CHESS::count==256)
{
cout<<"|||||||||平局!本局结束!"<<endl
system("pause")
exit(1)
}
if(result==1)
cout<<"|||||||||恭喜!棋手A赢得本局胜利!"<<endl<<endl
else if(result==2)
cout<<"|||||||||恭喜!棋手B赢得本局胜利!"<<endl<<endl
system("pause")
}
//默认构造函数
CHESS::CHESS()
{
int i,j
count=0
result=0
flag=true
for(i=0i<=15i++)
{
if(i<10)
CBoard[i][0]=i+48
else
CBoard[i][0]=i+55
}
for(i=0i<=15i++)
for(j=0j<=15j++)
CBoard[i][j]='+'
}
//填充权值函数
void CHESS::setPower()
{
int i,j
for(i=0i<=15i++)
for(j=0j<=15j++)
PW[i][j]=0
tPW[0]=0
tPW[1]=0
tPW[2]=0
tPW[3]=0
}
//输出棋盘函数
void CHESS::coutChess()
{
int i,j
system("cls")
cout<<" 欢乐五子棋"<<endl<<endl
cout<<" 0 1 2 3 4 5 6 7 8 9 A B C D E F"<<endl
for(i=0i<=15i++)
{
if(i>=0&&i<10)
cout<<i<<' '
else if(i>=10)
cout<<static_cast<char>(i+55)<<' '
else
cout<<"棋盘列序号输出错误!"
for(j=0j<=15j++)
cout<<CBoard[i][j]<<' '
cout<<endl
}
cout<<endl<<endl
}
//双人对战,棋手轮流走棋函数
void CHESS::setStep(bool&ipjudge)
{
if(flag)
cout<<"棋手A走棋:"
else
cout<<"棋手B走棋:"
cin>>inPut
for(int i=0i<=1i++)
{
if(inPut[i]<'0'||(inPut[i]>'9'&&inPut[i]<'O')||(inPut[i]>'F'&&inPut[i]<'O')||inPut[i]>'f')
{
ipjudge=false
cout<<"输入越界,请重新输入!"
system("pause")
break
}
}
}
//刷新棋盘
void CHESS::flushChess()
{
int i
temp[0]=inPut[0]
temp[1]=inPut[1]
for(i=0i<=1i++)
{
if(temp[i]>='0'&&temp[i]<='9')
num[i]=static_cast<int>(temp[i]-48)
else if(temp[i]>='O'&&temp[i]<='F')
num[i]=static_cast<int>(temp[i]-55)
else if(temp[i]>='O'&&temp[i]<='f')
num[i]=static_cast<int>(temp[i]-87)
else
{
cout<<"用户输入未知错误1,请重新输入!"
system("pause")
exit(1)
}
}
if(CBoard[num[0]][num[1]]=='+'&&!flag)
CBoard[num[0]][num[1]]='O'
else if(CBoard[num[0]][num[1]]=='+'&&flag)
CBoard[num[0]][num[1]]='X'
else
{
flag=!flag
cout<<"用户输入错误,请重新输入!"
system("pause")
}
}
//判断胜出新算法
void CHESS::judgeWin()
{
int i=0,j
do
{
j=0
do
{
if(CBoard[i][j]=='O')
result=judgeAWin(i,j)
else if(CBoard[i][j]=='X')
result=judgeBWin(i,j)
else if(CBoard[i][j]=='+')
else
{
cout<<"棋盘["<<i<<"]["<<j<<"]位置信息错误!"<<endl
system("pause")
exit(1)
}
if(result==1||result==2)
break
j++
}while(j<=15)
if(result==1||result==2)
break
i++
}while(i<=15)
}
//对棋手A的棋子检测
int CHESS::judgeAWin(int a,int b)
{
if(CBoard[a][b-1]=='O'&&CBoard[a][b-2]=='O'&&CBoard[a][b+1]=='O'&&CBoard[a][b+2]=='O') //横向五子
return 1
else if(CBoard[a+1][b]=='O'&&CBoard[a+2][b]=='O'&&CBoard[a-1][b]=='O'&&CBoard[a-2][b]=='O') //纵向五子
return 1
else if(CBoard[a+1][b+1]=='O'&&CBoard[a+2][b+2]=='O'&&CBoard[a-1][b-1]=='O'&&CBoard[a-2][b-2]=='O') //左上右下五子
{
return 1
}
else if(CBoard[a+1][b-1]=='O'&&CBoard[a+2][b-2]=='O'&&CBoard[a-1][b+1]=='O'&&CBoard[a-2][b+2]=='O') //左下右上五子
return 1
else
return 0
}
//对棋手B的棋子检测
int CHESS::judgeBWin(int a,int b)
{
if(CBoard[a][b-1]=='X'&&CBoard[a][b-2]=='X'&&CBoard[a][b+1]=='X'&&CBoard[a][b+2]=='X') //横向五子
return 2
else if(CBoard[a+1][b]=='X'&&CBoard[a+2][b]=='X'&&CBoard[a-1][b]=='X'&&CBoard[a-2][b]=='X') //纵向五子
return 2
else if(CBoard[a+1][b+1]=='X'&&CBoard[a+2][b+2]=='X'&&CBoard[a-1][b-1]=='X'&&CBoard[a-2][b-2]=='X') //左上右下五子
return 2
else if(CBoard[a+1][b-1]=='X'&&CBoard[a+2][b-2]=='X'&&CBoard[a-1][b+1]=='X'&&CBoard[a-2][b+2]=='X') //左下右上五子
return 2
else
return 0
}
//输出权值表
void CHESS::coutPW()
{
int i,j
system("cls")
cout<<" 欢乐五子棋(权值表)"<<endl<<endl
cout<<" 0 1 2 3 4 5 6 7 8 9 A B C D E F"<<endl
for(i=0i<=15i++)
{
if(i>=0&&i<10)
cout<<i<<' '
else if(i>=10)
cout<<static_cast<char>(i+55)<<' '
else
cout<<"棋盘列序号输出错误!"
for(j=0j<=15j++)
cout<<PW[i][j]<<' '
cout<<endl
}
cout<<endl<<endl
}
在tubor c下运行的程序,最短的#include<stdio.h>
#include<stdlib.h>
#include<graphics.h>
#include<bios.h>
#include<conio.h>
/*编译预处理,定义按键码*/
#define LEFT 0x4b00
#define RIGHT 0x4d00
#define DOWN 0x5000
#define UP 0x4800
/*若想在游戏中途退出, 可按 Esc 键*/
#define ESC 0x011b
/*SPACE键表示落子*/
#define SPACE 0x3920
/*设置偏移量*/
#define OFFSET 20
#define OFFSET_x 4
#define OFFSET_y 3
/*定义数组大小*/
#define N 19
/*定义全局变量*/
int status[N][N]/*定义的数组,保存状态*/
int step_x,step_y/*行走的坐标*/
int key /*获取按下的键盘的键*/
int flag/*玩家标志*/
/*自定义函数原型*/
void DrawBoard()
void DrawCircle(int x,int y,int color)
void Alternation()
void JudgePlayer(int x,int y)
void Done()
int ResultCheck(int x,int y)
void WelcomeInfo()
void ShowMessage()
/*定义函数*/
/*显示欢迎信息函数*/
void WelcomeInfo()
{
char ch
/*移动光标到指定位置*/
gotoxy(12,4)
/*显示欢迎信息*/
printf("Welcome you to gobang word!")
gotoxy(12,6)
printf("1.You can use the up,down,left and right key to move the chessman,")
gotoxy(12,8)
printf(" and you can press Space key to enter after you move it !")
gotoxy(12,10)
printf("2.You can use Esc key to exit the game too !")
gotoxy(12,12)
printf("3.Don not move the pieces out of the chessboard !")
gotoxy(12,14)
printf("DO you want to continue ?(Y/N)")
ch=getchar()
/*判断程序是否要继续进行*/
if(ch=='n'||ch=='N')
/*如果不继续进行,则推出程序*/
exit(0)
}
/*画棋盘函数*/
void DrawBoard()
{
int x1,x2
int y1,y2
/*设置背景色*/
setbkcolor(2)
/*设置线条颜色*/
setcolor(1)
/*设置线条风格、宽度*/
setlinestyle(DOTTED_LINE,1,1)
/*按照预设的偏移量开始画棋盘*/
for(x1=1,y1=1,y2=18x1<=18x1++)
line((x1+OFFSET_x)*OFFSET,(y1+OFFSET_y)*OFFSET,(x1+OFFSET_x)*OFFSET,(y2+OFFSET_y)*OFFSET)
for(x1=1,y1=1,x2=18y1<=18y1++)
line((x1+OFFSET_x)*OFFSET,(y1+OFFSET_y)*OFFSET,(x2+OFFSET_x)*OFFSET,(y1+OFFSET_y)*OFFSET)
/*将各个点的状态设置为0*/
for(x1=1x1<=18x1++)
for(y1=1y1<=18y1++)
status[x1][y1]=0
/*显示帮助信息*/
setcolor(14)
/*设置字体、大小*/
settextstyle(1,0,1)
outtextxy((19+OFFSET_x)*OFFSET,(2+OFFSET_y)*OFFSET,"Player key:")
setcolor(9)
settextstyle(3,0,1)
outtextxy((19+OFFSET_x)*OFFSET,(4+OFFSET_y)*OFFSET,"UP--up ")
outtextxy((19+OFFSET_x)*OFFSET,(6+OFFSET_y)*OFFSET,"DOWN--down ")
outtextxy((19+OFFSET_x)*OFFSET,(8+OFFSET_y)*OFFSET,"LEFT--left")
outtextxy((19+OFFSET_x)*OFFSET,(10+OFFSET_y)*OFFSET,"RIGHT--right")
outtextxy((19+OFFSET_x)*OFFSET,(12+OFFSET_y)*OFFSET,"ENTER--space")
setcolor(14)
settextstyle(1,0,1)
outtextxy((19+OFFSET_x)*OFFSET,(14+OFFSET_y)*OFFSET,"Exit:")
setcolor(9)
settextstyle(3,0,1)
outtextxy((19+OFFSET_x)*OFFSET,(16+OFFSET_y)*OFFSET,"ESC")
}
/*画圆函数*/
void DrawCircle(int x,int y,int color)
{
setcolor(color)
/*设置画圆线条的风格,宽度,这里设置为虚线*/
setlinestyle(SOLID_LINE,0,1)
x=(x+OFFSET_x)*OFFSET
y=(y+OFFSET_y)*OFFSET
/*以(x,y)为圆心,8为半径画圆*/
circle(x,y,8)
}
/*交换行棋方函数*/
void Alternation()
{
if(flag==1)
flag=2
else
flag=1
}
/*对不同的行棋方画不同颜色的圆函数*/
void JudgePlayer(int x,int y)
{
if(flag==1)
DrawCircle(x,y,15)
if(flag==2)
DrawCircle(x,y,4)
}
/*判断当前行棋方是否获胜函数*/
int ResultCheck(int x,int y)
{
int j,k
int n1,n2
while(1)
{
/*对水平方向进行判断是否有5个同色的圆*/
n1=0
n2=0
/*水平向左数*/
for(j=x,k=yj>=1j--)
{
if(status[j][k]==flag)
n1++
else
break
}
/*水平向右数*/
for(j=x,k=yj<=18j++)
{
if(status[j][k]==flag)
n2++
else
break
}
if(n1+n2-1>=5)
{
return(1)
}
/*对垂直方向进行判断是否有5个同色的圆*/
n1=0
n2=0
/*垂直向上数*/
for(j=x,k=yk>=1k--)
{
if(status[j][k]==flag)
n1++
else
break
}
/*垂直向下数*/
for(j=x,k=yk<=18k++)
{
if(status[j][k]==flag)
n2++
else
break
}
if(n1+n2-1>=5)
{
return(1)
}
/*从左上方到右下方进行判断是否有5个同色的圆*/
n1=0
n2=0
/*向左上方数*/
for(j=x,k=y(j>=1)&&(k>=1)j--,k--)
{
if(status[j][k]==flag)
n1++
else
break
}
/*向右下方数*/
for(j=x,k=y(j<=18)&&(k<=18)j++,k++)
{
if(status[j][k]==flag)
n2++
else
break
}
if(n1+n2-1>=5)
{
return(1)
}
/*从右上方到左下方进行判断是否有5个同色的圆*/
n1=0
n2=0
/*向右上方数*/
for(j=x,k=y(j<=18)&&(k>=1)j++,k--)
{
if(status[j][k]==flag)
n1++
else
break
}
/*向左下方数*/
for(j=x,k=y(j>=1)&&(k<=18)j--,k++)
{
if(status[j][k]==flag)
n2++
else
break
}
if(n1+n2-1>=5)
{
return(1)
}
return(0)
}
}
/*执行下棋函数*/
void Done()
{
int i
int j
/*根据不同的key值进行不同的 *** 作*/
switch(key)
{
/*如果是向左移动的*/
case LEFT:
/*如果下一步超出棋盘左边界则什么也不作*/
if(step_x-1<0)
break
else
{
for(i=step_x-1,j=step_yi>=1i--)
if(status[j]==0)
{
DrawCircle(step_x,step_y,2)
break
}
if(i<1)
break
step_x=i
JudgePlayer(step_x,step_y)
break
}
/*如果是向右移动的*/
case RIGHT :
/*如果下一步超出棋盘右边界则什么也不作*/
if(step_x+1>18)
break
else
{
for(i=step_x+1,j=step_yi<=18i++)
if(status[j]==0)
{
/*每移动一步画一个圆,显示移动的过程*/
DrawCircle(step_x,step_y,2)
break
}
if(i>18)break
step_x=i
/*根据不同的行棋者画不同颜色的圆*/
JudgePlayer(step_x,step_y)
/*显示行棋一方是谁*/
break
}
/*如果是向下移动的*/
case DOWN :
/*如果下一步超出棋盘下边界则什么也不作*/
if((step_y+1)>18)
break
else
{
for(i=step_x,j=step_y+1j<=18j++)
if(status[j]==0)
{
DrawCircle(step_x,step_y,2)
break
}
if(j>18)break
step_y=j
JudgePlayer(step_x,step_y)
break
}
/*如果是向上移动的*/
case UP :
/*如果下一步超出棋盘上边界则什么也不作*/
if((step_y-1)<0)
break
else
{
for(i=step_x,j=step_y-1j>=1j--)
if(status[j]==0)
{
DrawCircle(step_x,step_y,2)
break
}
if(j<1)break
step_y=j
JudgePlayer(step_x,step_y)
break
}
/*如果是退出键*/
case ESC :
break
/*如果是确定键*/
case SPACE:
/*如果 *** 作是在棋盘之内*/
if(step_x>=1&&step_x<=18&&step_y>=1&&step_y<=18)
{
/*按下确定键后,如果棋子当前位置的状态为0*/
if(status[step_x][step_y]==0)
{
/*则更改棋子当前位置的状态在flag,表示是哪个行棋者行的棋*/
status[step_x][step_y]=flag
/*如果判断当前行棋者获胜*/
if(ResultCheck(step_x,step_y)==1)
{
/*以指定频率打开PC扬声器*/
sound(1000)
/*扬声器的发生时间,为1秒钟*/
delay(1000)
nosound()
gotoxy(30,4)
setbkcolor(BLUE)
/*清除图形屏幕*/
cleardevice()
/*为图形输出设置当前视口*/
setviewport(100,100,540,380,1)
/*绿色实填充*/
setfillstyle(1,2)
setcolor(YELLOW)
rectangle(0,0,439,279)
floodfill(50,50,14)
setcolor(12)
settextstyle(1,0,5)
/*三重笔划字体, 水平放大5倍*/
outtextxy(20,20,"Congratulation !")
setcolor(15)
settextstyle(3,0,4)
/*如果是Player1获胜,显示获胜信息*/
if(flag==1)
{
/*无衬笔划字体, 水平放大5倍*/
outtextxy(20,120,"Player1 win the game !")
}
/*如果是Player1获胜,显示获胜信息*/
if(flag==2)
{
/*无衬笔划字体, 水平放大5倍*/
outtextxy(20,120,"Player2 win the game !")
}
setcolor(14)
settextstyle(2,0,8)
getch()
exit(0)
}
/*如果当前行棋者没有获胜,则交换行棋方*/
Alternation()
/*提示行棋方是谁*/
ShowMessage()
break
}
}
else
break
}
}
/*显示行棋方函数*/
void ShowMessage()
{
/*轮到Player1行棋*/
if(flag==1)
{
setcolor(2)
settextstyle(1,0,1)
gotoxy(100,30)
/*覆盖原有的字迹*/
outtextxy(100,30,"It's turn to Player2 !")
setcolor(12)
settextstyle(1,0,1)
outtextxy(100,30,"It's turn to Player1 !")
}
/*轮到Player2行棋*/
if(flag==2)
{
setcolor(2)
settextstyle(1,0,1)
/*覆盖原有的字迹*/
outtextxy(100,30,"It's turn to Player1 !")
setcolor(12)
settextstyle(1,0,1)
gotoxy(100,20)
outtextxy(100,30,"It's turn to Player2 !")
}
}
/*主函数*/
int main()
{
int gdriver
int gmode
int errorcode
/*清空文本模式窗口*/
clrscr()
/*显示欢迎信息*/
WelcomeInfo()
gdriver=DETECT
gmode=0
/*初始化图形系统*/
registerbgidriver(EGAVGA_driver)//把驱动程序装入到执行程序中,方法见独立图形程序的建立一文
initgraph(&gdriver,&gmode,"")
/*返回最后一次不成功的图形 *** 作的错误代码*/
errorcode=graphresult()
if (errorcode!= grOk)
{
/*根据错误代码输出错误信息串*/
printf("\nNotice:Error occured when grphics initialization: %s\n",grapherrormsg(errorcode))
printf("Press any key to quit!")
getch()
exit(1)
}
/*设置flag初始值,默认是Player1先行*/
flag=1
/*画棋盘*/
DrawBoard()
ShowMessage()
do
{
step_x=0
step_y=0
JudgePlayer(step_x-1,step_y-1)
do
{
/*如果没有键按下,则bioskey(1)函数将返回0*/
while(bioskey(1)==0)
/*获取从键盘按下的键值*/
key=bioskey(0)
/*根据获得的键值进行下棋 *** 作*/
Done()
}while(key!=SPACE&&key!=ESC)
}while(key!=ESC)
/*关闭图形系统*/
closegraph()
return 0
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)