文章目录
一、游戏菜单
void menu()
{
printf("*****************************\n");
printf("********** 1. play **********\n");
printf("********** 0. exit **********\n");
printf("*****************************\n");
游戏菜单是给玩家选择是否进入游戏的界面
二、主函数
int main()
{
srand((unsigned int)time(NULL));
int input = 0;
do
{
menu();
printf("请选择:>");
scanf("%d", &input);
switch (input)
{
case 1:
game();
break;
case 0:
printf("退出游戏\n");
break;
default:
printf("选择错误,重新选择\n");
}
} while (input);
return 0;
}
这里的逻辑是:进入游戏菜单后,玩家输入 1,即可进入游戏,玩家输入0,即可退出游戏。
三、game()
void game()
{
int ret;
char board[3][3] = { 0 };
init_board(board, ROW, COL);
display_board(board,ROW,COL);
while (1)
{
player_move(board, ROW, COL);
ret = is_win(board, ROW, COL);
if (ret != 'C')
{
break;
}
computer_move(board, ROW, COL);
ret = is_win(board, ROW, COL);
if (ret != 'C')
{
break;
}
display_board(board, ROW, COL);
}
if (ret == 'Q')
{
printf("平局\n");
}
else if (ret == '*')
{
printf("玩家赢\n");
}
else if (ret == '#')
{
printf("电脑赢\n");
}
}
这部分是实现游戏流程的逻辑。例如,玩家下棋,电脑下棋,打印棋盘等等的逻辑先后以及循环逻辑
。
四、init_board()
void init_board(char board[ROW][COL], int row, int col)
{
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
board[i][j] = ' ';
}
}
}
init_board函数的目的是初始化棋盘,将棋盘的九个格子的内容初始化为‘空格’,那么为什么不可以初始化为0呢,打印出来我们同样看不见。这里的原因是打印出来0是不占字符的,它不仅看不见,而且还不占位置。所以,如果使用0代替空格的话,打印出来的效果如下:
由于0不占位置,所以打印出来的第一行的’|‘与第二行的’|‘无法对齐。
而正确使用’空格‘打印出来的效果才是正确的
如下:
五、display_board()
void display_board(char board[ROW][COL], int row, int col)
{
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
printf(" %c ",board[i][j]);
if (j < col - 1)
printf("|");
}
printf("\n");
if (i < row - 1)
{
for (int j = 0; j < col; j++)
{
printf("---");
if (j < col - 1)
printf("|");
}
}
printf("\n");
}
}
这段代码的作用是将数组中的字符以及三子棋的棋盘打印出来,打印效果如下:
打印时,我们需要注意的几点是,最后一列不要打印’|‘,最后一行不要打印’—‘
我们就可以用if语句来控制打印。所以采用了if(i<row-1)以及if(j<col-1)放在打印这两个字符的前面
六、player_move()
void player_move(char board[ROW][COL], int row, int col)
{
int x, y;
while (1)
{
printf("请输入要下棋的坐标\n");
printf("玩家下棋:>");
scanf("%d %d", &x, &y);
if (x > 0 && x <= col && y > 0 && y <= row)
{
if (board[x - 1][y - 1] == ' ')
{
board[x-1][y-1] = '*';
break;
}
else
{
printf("该坐标已被占用,请重新输入");
}
}
else
{
printf("坐标非法,请重新输入");
}
}
}
player_move()函数的作用是,让玩家下棋,由于玩家认为的坐标与实际数组对应的位置相差1,所以当玩家输入坐标后,在对应的x-1,y-1的位置上的数组改为’*‘,同时要保证输入数据的有效性
七、computer_move()
void computer_move(char board[ROW][COL], int row, int col)
{
while (1)
{
int x = rand() % row;
int y = rand() % col;
if (board[x][y] == ' ')
{
board[x][y] = '#';
break;
}
}
}
由于学艺不精,我无法用c语言实现电脑智能下棋,只能让电脑随机下棋。采用rand函数对随机数取余。在对应坐标位置上将数组上的‘空格’,改为‘#’;
八、is_win()
char is_win(char board[ROW][COL], int row, int col)
{
//横
for (int i = 0; i < row; i++)
{
if (board[i][0] == board[i][1] && board[i][2] == board[i][1] && board[i][0] != ' ')
{
return board[i][0];
}
}
//竖
for (int i = 0; i < col; i++)
{
if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[0][i] != ' ')
{
return board[0][i];
}
}
//斜
if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[0][0] != ' ')
{
return board[0][0];
}
if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[0][2] != ' ')
{
return board[0][2];
}
if (is_full(board,row,col) == 1)
{
return 'Q';
}
return 'C';
}
该函数的作用是对棋盘进行判断游戏是否继续;若游戏终止,则返回对应的结果,若玩家获胜,则返回‘*’,若电脑获胜,则返回‘#’;
九、is_full()
int is_full(char board[ROW][COL], int row, int col)
{
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
if (board[i][j] == ' ')
{
return 0;
}
}
}
return 1;
}
is_full函数的目的是判断棋盘是否以及满了,该函数与is_win函数搭配使用。为is_win函数功能的完成做铺垫。
总结-完整代码
1.game.h
#pragma once
#define _CRT_SECURE_NO_WARNINGS 1
#define ROW 3
#define COL 3
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
void display_board(char board[ROW][COL],int row,int col);
void init_board(char board[ROW][COL], int row, int col);
void player_move(char board[ROW][COL], int row, int col);
void computer_move(char board[ROW][COL], int row, int col);
char is_win(char board[ROW][COL], int row, int col);
2.game.c
#pragma once
#include "game.h"
void init_board(char board[ROW][COL], int row, int col)
{
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
board[i][j] = ' ';
}
}
}
void display_board(char board[ROW][COL], int row, int col)
{
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
printf(" %c ",board[i][j]);
if (j < col - 1)
printf("|");
}
printf("\n");
if (i < row - 1)
{
for (int j = 0; j < col; j++)
{
printf("---");
if (j < col - 1)
printf("|");
}
}
printf("\n");
}
}
void player_move(char board[ROW][COL], int row, int col)
{
int x, y;
while (1)
{
printf("请输入要下棋的坐标\n");
printf("玩家下棋:>");
scanf("%d %d", &x, &y);
if (x > 0 && x <= col && y > 0 && y <= row)
{
if (board[x - 1][y - 1] == ' ')
{
board[x-1][y-1] = '*';
break;
}
else
{
printf("该坐标已被占用,请重新输入");
}
}
else
{
printf("坐标非法,请重新输入");
}
}
}
void computer_move(char board[ROW][COL], int row, int col)
{
while (1)
{
int x = rand() % row;
int y = rand() % col;
if (board[x][y] == ' ')
{
board[x][y] = '#';
break;
}
}
}
int is_full(char board[ROW][COL], int row, int col)
{
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
if (board[i][j] == ' ')
{
return 0;
}
}
}
return 1;
}
char is_win(char board[ROW][COL], int row, int col)
{
//横
for (int i = 0; i < row; i++)
{
if (board[i][0] == board[i][1] && board[i][2] == board[i][1] && board[i][0] != ' ')
{
return board[i][0];
}
}
//竖
for (int i = 0; i < col; i++)
{
if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[0][i] != ' ')
{
return board[0][i];
}
}
//斜
if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[0][0] != ' ')
{
return board[0][0];
}
if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[0][2] != ' ')
{
return board[0][2];
}
if (is_full(board,row,col) == 1)
{
return 'Q';
}
return 'C';
}
3.test.c
#define _CRT_SECURE_NO_WARNINGS 1
#include "game.h"
void menu()
{
printf("*****************************\n");
printf("********** 1. play **********\n");
printf("********** 0. exit **********\n");
printf("*****************************\n");
}
void game()
{
int ret;
char board[3][3] = { 0 };
init_board(board, ROW, COL);
display_board(board,ROW,COL);
while (1)
{
player_move(board, ROW, COL);
ret = is_win(board, ROW, COL);
if (ret != 'C')
{
break;
}
computer_move(board, ROW, COL);
ret = is_win(board, ROW, COL);
if (ret != 'C')
{
break;
}
display_board(board, ROW, COL);
}
if (ret == 'Q')
{
printf("平局\n");
}
else if (ret == '*')
{
printf("玩家赢\n");
}
else if (ret == '#')
{
printf("电脑赢\n");
}
}
int main()
{
srand((unsigned int)time(NULL));
int input = 0;
do
{
menu();
printf("请选择:>");
scanf("%d", &input);
switch (input)
{
case 1:
game();
break;
case 0:
printf("退出游戏\n");
break;
default:
printf("选择错误,重新选择\n");
}
} while (input);
return 0;
}
赶紧让代码在你的编译器上跑起来试试叭~