版权声明:转载请注明出处 https://blog.csdn.net/Hanoi_ahoj/article/details/83187987
简单分析
- 需要个游戏控制函数,决定是继续游戏,还是退出程序。
- 人走完后,电脑走棋。
- 每次走完棋,需要显示当前棋盘状态。
- 在每次走完后,需要判断是否胜利。
- 当三种相同的在一条线上时,胜利。
- 当地图填满时,还没有胜利者,则为平局。
0. 地图大小和坐标
#define ROW 3
#define COL 3
typedef struct
{
int x;
int y;
}Point;
1. 菜单
void game_menu()
{
printf("*********************\n");
printf("*** 1.play 0.exit ***\n");
printf("*********************\n");
}
2. 主函数
输入1,开始玩游戏,调用游戏控制函数。
int main(int argc, const char * argv[])
{
int input = 0;
do
{
game_menu();
printf(">");
scanf("%d", &input);
switch (input)
{
case 1:
game_ctrl();
break;
case 0:
printf("Bye!\n");
break;
default:
printf("Input Error!\n");
break;
}
} while (input);
return 0;
}
3. 初始化地图
// 初始化地图
void board_init(char board[ROW][COL], int row, int col)
{
memset(&board[0][0], ' ', row*col*sizeof(board[0][0]));
}
4. 打印地图
// 展示地图信息
void board_print(char board[ROW][COL], int row, int col)
{
system("clear");
for (int i=0; i<row; i++)
{
for (int j=0; j<col; j++)
{
printf(" %c ",board[i][j]);
if (j<row-1)
{
printf("|");
}
}
printf("\n");
if (i<row-1)
{
for (int j=0; j<col; j++)
{
printf("---");
if (j<row-1)
{
printf("|");
}
}
printf("\n");
}
}
}
5. 玩家走
// 玩家走
void player_move(char board[ROW][COL], int row, int col)
{
Point p;
printf("your turn:\n");
while (true)
{
printf(">");
scanf("%d%d", &p.x, &p.y);
if (p.x>0&&p.x<=row && p.y>0&&p.y<=col)
{
if (board[p.x-1][p.y-1] == ' ')
{
board[p.x-1][p.y-1] = 'X';
break;
}
else
{
printf("illegal!\n");
}
}
else
{
printf("illegal!\n");
}
}
}
6. 电脑走
// 电脑走
void computer_move(char board[ROW][COL], int row, int col)
{
Point p;
while (true)
{
p.x = rand()%row;
p.y = rand()%col;
if (board[p.x][p.y] == ' ')
{
board[p.x][p.y] = 'O';
break;
}
}
}
7. 胜利判定
// 胜利判断
char is_win(char board[ROW][COL], int row, int col)
{
int i = 0;
for(i=0; i<row; i++)
{
if(board[i][0]==board[i][1] && board[i][1]==board[i][2] && board[i][0] != ' ')
{
return board[i][0];
}
}
for(i=0; i<col; i++)
{
if(board[0][i]==board[1][i] && board[1][i]==board[2][i] && board[1][i] != ' ')
{
return board[1][i];
}
}
if(board[0][0]==board[1][1] && board[1][1]==board[2][2] && board[1][1] != ' ')
return board[1][1];
if(board[0][2]==board[1][1] && board[1][1]==board[2][0] && board[1][1] != ' ')
return board[1][1];
//判断平局
if(is_full(board, row, col) == 1)
{
return 'Q';
}
//继续
return ' ';
}
8. 平局判定
int is_full(char board[ROW][COL], int row, int col)
{
int i = 0;
int j = 0;
for(i=0; i<row; i++)
{
for(j=0; j<col; j++)
{
if(board[i][j] == ' ')
return 0;
}
}
return 1;
}
9. 游戏控制函数
void game_ctrl()
{
char board[ROW][COL] = { 0 };
board_init(board, ROW, COL);
board_print(board, ROW, COL);
char ret = 0;
while (true)
{
player_move(board, ROW, COL);
ret = is_win(board, ROW, COL);
if (ret != ' ')
{
break;
}
board_print(board, ROW, COL);
computer_move(board, ROW, COL);
ret = is_win(board, ROW, COL);
if (ret != ' ')
{
break;
}
board_print(board, ROW, COL);
}
board_print(board, ROW, COL);
if(ret == 'X')
printf("you win!\n");
else if(ret == 'O')
printf("you lose!\n");
else if(ret == 'Q')
printf("again?!\n");
}
10. 优化
上述代码中,电脑走棋是随机生成的,并没有进行任何判断,所以上面的主要是怎么让电脑赢,哈哈哈。
- 电脑走棋优化:
- 扫描棋盘(扫描行,扫描列,扫描对角线)。增加权重信息,玩家将要胜利的权重大于自己胜利的权重,下一步操作为(权重较高的那个操作)堵住玩家下一步要走的路。
- 可玩性优化:
- 增加难度选择
- 玩家自定义棋子图标
- 背景音乐
// 扫描行 如果玩家即将胜利,返回一个他下一步的棋子位置,如果没有,返回(-1,-1)点
Point scan_row(char board[ROW][COL], int row, int col)
{
Point p;
p.x = -1;
p.y = -1;
for (int i=0; i<row; i++)
{
if (board[i][0]==board[i][1]&&board[i][0]=='X'&&board[i][2]==' ')
{
p.x = i;
p.y = 2;
return p;
}
else if(board[i][1]==board[i][2]&&board[i][1]=='X'&&board[i][0]==' ')
{
p.x = i;
p.y = 0;
return p;
}
else
{
return p;
}
}
return p;
}
// 扫描列 如果玩家即将胜利,返回一个他下一步的棋子位置,如果没有,返回(-1,-1)点
Point scan_col(char board[ROW][COL], int row, int col)
{
Point p;
p.x = -1;
p.y = -1;
for (int i=0; i<row; i++)
{
if (board[0][i]==board[1][i]&&board[0][i]=='X'&&board[2][i]==' ')
{
p.x = 2;
p.y = i;
return p;
}
else if(board[1][i]==board[2][i]&&board[1][i]=='X'&&board[0][i]==' ')
{
p.x = 0;
p.y = i;
return p;
}
else
{
return p;
}
}
return p;
}