游戏截图
源代码
person.h
//玩家对战
void person()
{
int i,j;
initMap(map);
//打印棋局
displayMap(map);
//未分出胜负且棋局未落满子前无限循环
while(1)
{
//获取玩家下子位置
getXY(&i,&j);
//玩家落子
setPiece(map,i,j);
//清屏
system("cls");
//打印棋局
displayMap(map);
//玩家落子后判断是否已经分出胜负
if(isWin(map)==1)
{
//输出获胜方
displayWinner();
break;
}
//是否棋局已满
else if(count==row*col)
{
printf("平局!\n");
break;
}
//交替到对手回合
exchangeTurn();
}
}
computer.h
//局面价值
int getSum(char map[][col])
{
int sumO=0,sumX=0;
int i,j;
for(i=0;i<row;i++)
{
for(j=0;j<col;j++)
{
if(map[i][j]=='O')
{
sumO+=score[i][j];
}
else if(map[i][j]=='X')
{
sumX+=score[i][j];
}
}
}
return sumX-sumO;
}
//思考
void think(char map[][col])
{
int canWin=0;
int i,j;
int x=-1,y=-1;
int sum;
int maxSum=-20;
count++;
for(i=0;i<row;i++)
{
for(j=0;j<col;j++)
{
if(map[i][j]==m)
{
map[i][j]='X';
//能获胜,直接落子此处
if(isWin(map))
{
return;
}
//不能获胜,落子在分数最多的地方
else
{
map[i][j]='O';
if(isWin(map))
{
map[i][j]='X';
return;
}
map[i][j]='X';
sum=getSum(map);
if(sum>maxSum)
{
maxSum=sum;
x=i;
y=j;
}
}
map[i][j]=m;
}
}
}
map[x][y]='X';
}
void computer()
{
int i,j;
char computerType='X';
initMap(map);
//打印棋局
displayMap(map);
//未分出胜负且棋局未落满子前无限循环
while(1)
{
//电脑落子
if(nowType==computerType)
{
printf("电脑落子:");
think(map);
}
//玩家落子
else
{
//获取玩家下子位置
getXY(&i,&j);
//玩家落子
setPiece(map,i,j);
}
//清屏
system("cls");
//打印棋局
displayMap(map);
//玩家落子后判断是否已经分出胜负
if(isWin(map)==1)
{
//输出获胜方
displayWinner();
break;
}
//是否棋局已满
else if(count==row*col)
{
printf("平局!\n");
break;
}
//交替到对手回合
exchangeTurn();
}
}
main.c
#include<stdio.h>
#include<stdlib.h>
//棋局
char map[3][3];
//行列
int row=3,col=3;
//棋子类型
char o='O',x='X',m=' ';
//当前棋子类型
char nowType='O';
//已落子数量
int count=0;
//初始化棋局
void initMap(char map[][col])
{
int i,j;
for(i=0;i<row;i++)
{
for(j=0;j<col;j++)
{
map[i][j]=m;
}
}
}
//打印当前棋局
void displayMap(char map[][col])
{
int i,j;
printf(" ");
for(i=0;i<col;i++)
{
printf("%d ",i);
}
printf("\n ");
for(i=0;i<2*col+1;i++)
{
printf("*");
}
printf("\n");
for(i=0;i<row;i++)
{
printf("%d ",i);
for(j=0;j<col;j++)
{
printf("%c ",map[i][j]);
}
printf("\n ");
for(j=0;j<2*col+1;j++)
{
printf("*");
}
printf("\n");
}
}
//获取用户输入
void getXY(int *i,int *j)
{
while(1)
{
printf("落子方:%c\n",nowType);
printf("落子位置(x,y)=");
scanf("%d %d",i,j);
if(*i<0||*i>=row||*j<0||*j>=col||map[*i][*j]!=m)
{
printf("输入不合法!\n");
}
else
{
return;
}
}
}
//交替下子
void exchangeTurn()
{
if(nowType==o)
{
nowType=x;
}
else
{
nowType=o;
}
}
//下子
void setPiece(char map[][col],int i,int j)
{
map[i][j]=nowType;
count++;
}
//判断是否分出胜负,分别从横竖斜三个方向数数
int isWin(char map[][col])
{
int i,j;
int flagR,flagC;
for(i=0;i<row;i++)
{
flagR=0,flagC=0;
for(j=0;j<col;j++)
{
if(map[i][j]==o)
{
flagR++;
}
else if(map[i][j]==x)
{
flagR--;
}
if(map[j][i]==o)
{
flagC++;
}
else if(map[j][i]==x)
{
flagC--;
}
}
if(flagR==col||flagC==col||flagR==(-col)||flagC==(-col))
{
return 1;
}
}
flagR=0,flagC=0;
for(i=0,j=0;i<row&&j<col;i++,j++)
{
if(map[i][j]==o)
{
flagR++;
}
else if(map[i][j]==x)
{
flagR--;
}
if(map[i][col-j-1]==o)
{
flagC++;
}
else if(map[i][col-j-1]==x)
{
flagC--;
}
}
if(flagR==col||flagC==col||flagR==(-col)||flagC==(-col))
{
return 1;
}
else
{
return 0;
}
}
//输出胜方
void displayWinner()
{
printf("%c方获得胜利!\n",nowType);
}
//给局面打分的基础表(站位分)
int score[3][3]={
{4,2,4},
{2,8,2},
{4,2,4}
};
//引入自定义头文件
#include"person.h"
#include"computer.h"
int main()
{
int gameType;
printf("1.人机对战\n其他.玩家对战\n");
scanf("%d",&gameType);
if(gameType==1)
{
computer();
}
else
{
person();
}
return 0;
}
代码解析
1、 其实棋类游戏设计最重要的就是模拟下棋的过程。
2、 我们知道井字棋是双方交替下子,一方执O,一方执X。
3、 比如O先下,玩家下完子后,我们判断一下此时他是否已经获胜(即是否出现横或竖或两斜线出现三子连珠的情况),没有获胜则判断是否已经将棋局下满子了,还是没有的话,轮到X的回合。再次执行此步骤。
4、 了解了过程就自然好设计了。因为棋局比较简单,我们用一个二维字符数组即可存储。落子位置用坐标(x,y),通过玩家输入即可进行模拟。