实现原理:基于二维数组
步骤:
1.首先写出主函数内容框架,如果需要用到其他函数,再封装调用即可。
int main()
{
int input = 0;
do {
menu();//菜单,游戏的初始界面
printf("输入1开始游戏,输入0结束游戏\n");
scanf("%d", &input);
switch (input)
{
case 1:
game();//游戏函数,用来实现三子棋
break;
case 0:
break;
default:
printf("输入错误,请重新输入:\n");
break;
}
} while (input);
return 0;
}
2.接下来封装menu( )和game( )函数,先完成简单的menu( )函数。
void menu()
{
printf("*************************************************\n");
printf("******* 1.play 0.exit ******\n");
printf("*************************************************\n");
}
根据个人喜好来设定游戏初始界面。
3.既然是下棋,那么首先就需要一个棋盘。
void init_board(char board[ROW][COL], int rows, int cols)//初始化棋盘
{
int i, j;
for (i = 0; i < rows; i++)
{
for (j = 0; j < cols; j++)
{
board[i][j] = ' ';//将数组初始化为空格
}
}
}
根据三子棋基于二维数组的原理,定义一个3x3的二维数组并将所有元素初始化为空格(至于为什么初始化为空格,后文将会给出解答);初始化了棋盘后,就要创建一个棋盘的样式。
void display_board(char board[ROW][COL], int rows, int cols)//打印棋盘
{
int i = 0;
for (i = 0; i < rows; i++)
{
printf(" %c | %c | %c \n", board[i][0], board[i][1], board[i][2]);
if (i < rows-1)
printf("---|---|---\n");
}
}
4.棋盘设定好后就进入游戏环节,假设玩家走x,电脑走0。
void player_move(char board[ROW][COL], int rows, int cols)//玩家走
{
int x = 0;
int y = 0;
while (1)
{
printf("请输入坐标>:");
scanf("%d%d", &x, &y);
--x;
--y;
if (((x >= 0) && (x < rows)) && ((y >= 0) && (y <= cols)))
{
if (board[x][y] == ' ')
{
board[x][y] = 'X';
break;
}
else
{
printf("输入有误,请重新输入\n");
}
}
else
{
printf("输入有误,请新重输入\n");
}
}
}
a.用数组存储玩家输入的信息就会出现这样一个问题,对于这个3x3的数组来说,元素只能由00到22,但是对于普通玩家来说,就会输入11到33之间的方案,所以为解决这个问题,就把玩家输入的数自减1后再存入数组。
b.既然要输入,那么就要判断什么时候可以输入,当某个位置为空格的时候可以输入,为x或者0时不可以输入,所以用if语句进行判断要输入的位置
c.现在就可以解释为什么要初始化棋盘了,初始化棋盘为空格时为了区分已经下过的区域和未下过的区域,给游戏规则“一处区域不能重复下子”提供了保障。
void computer_move(char board[ROW][COL], int rows, int cols)//电脑走
{
int x, y;
printf("电脑走\n");
while (1)
{
x = rand() % rows;//产生0-3的随机数
y = rand() % cols;
if (board[x][y] == ' ')
{
board[x][y] = '0';
break;
}
}
}
初学者无法做到让电脑有智慧的下子,只能做到在满足规则的条件下随机下子。
在这里要产生随机数就会用到rand()函数;
头文件:#include
srand(time(0));
int a = rand() % (20-10)+10;
这时还会发现再使用rand()函数时先使用srand()函数,这是因为rand()含税然能够生成随机数,但是重复几次后会发现几次生成的随机数都相同,原因是rand()函数每次生成随机数的起点相同,而srand()会设置供rand()使用的随机数种子,再陪和time函数的变化性,使每次生成随机数时都有不同的起点,这样才生成了真正的随机数。
5.先判断输赢
char is_win(char board[ROW][COL], int rows, int cols)//判断哪一个获胜
{
int i = 0;
int j = 0;
for (i = 0; i < rows; 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 < cols; 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[2][0] == board[1][1]) && (board[1][1] == board[0][2]) && (board[0][2] != ' '))//'/'相同
{
return board[0][0];
}
if (is_full(board, rows, cols))
{
return 'q';//平局
}
return ' ';//游戏继续
}
有可能棋盘下满了也未分出胜负,所以要考虑平局情况。
6.再判断平局
static int is_full(char board[ROW][COL], int rows, int cols)//检查是否平手
{
int i = 0;
int j = 0;
for (i = 0; i < rows; i++)
{
for (j = 0; j < cols; j++)
{
if (board[i][j] == ' ')
return 0;
}
}
return 1;
}
这是完整代码:
game.h
#ifndef __GAME__H__
#define __GAME__H__
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#define ROW 3
#define COL 3
void init_board(char board[ROW][COL], int rows, int cols);
void display_board(char board[ROW][COL], int rows, int cols);
void computer_move(char board[ROW][COL], int rows, int cols);
void player_move(char board[ROW][COL], int rows, int cols);
char is_win(char board[ROW][COL], int rows, int cols);
#endif //__GAME__H__
game.c
#define _CRT_SECURE_NO_WARNINGS 1
#include "game.h"
void init_board(char board[ROW][COL], int rows, int cols)//初始化棋盘
{
int i, j;
for (i = 0; i < rows; i++)
{
for (j = 0; j < cols; j++)
{
board[i][j] = ' ';//将数组初始化为空格
}
}
}
void display_board(char board[ROW][COL], int rows, int cols)//打印棋盘
{
int i = 0;
for (i = 0; i < rows; i++)
{
printf(" %c | %c | %c \n", board[i][0], board[i][1], board[i][2]);
if (i < rows-1)
printf("---|---|---\n");
}
}
void player_move(char board[ROW][COL], int rows, int cols)//玩家走
{
int x = 0;
int y = 0;
while (1)
{
printf("请输入坐标>:");
scanf("%d%d", &x, &y);
--x;
--y;
if (((x >= 0) && (x < rows)) && ((y >= 0) && (y <= cols)))
{
if (board[x][y] == ' ')
{
board[x][y] = 'X';
break;
}
else
{
printf("输入有误,请重新输入\n");
}
}
else
{
printf("输入有误,请新重输入\n");
}
}
}
void computer_move(char board[ROW][COL], int rows, int cols)//电脑走
{
int x, y;
printf("电脑走\n");
while (1)
{
x = rand() % rows;//产生0-3的随机数
y = rand() % cols;
if (board[x][y] == ' ')
{
board[x][y] = '0';
break;
}
}
}
char is_win(char board[ROW][COL], int rows, int cols)//判断哪一个获胜
{
int i = 0;
int j = 0;
for (i = 0; i < rows; 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 < cols; 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[2][0] == board[1][1]) && (board[1][1] == board[0][2]) && (board[0][2] != ' '))//'/'相同
{
return board[0][0];
}
if (is_full(board, rows, cols))
{
return 'q';//平局
}
return ' ';//游戏继续
}
static int is_full(char board[ROW][COL], int rows, int cols)//检查是否平手
{
int i = 0;
int j = 0;
for (i = 0; i < rows; i++)
{
for (j = 0; j < cols; j++)
{
if (board[i][j] == ' ')
return 0;
}
}
return 1;
}
test.c
#define _CRT_SECURE_NO_WARNINGS 1
#include "game.h"
void menu()
{
printf("*************************************************\n");
printf("******* 1.play 0.exit ******\n");
printf("*************************************************\n");
}
void game()
{
char ret;
char board[ROW][COL] = { 0 };//存放玩家和电脑下子的信息
init_board(board, ROW, COL);//初始化棋盘
display_board(board, ROW, COL);//打印棋盘
srand((unsigned int)time(NULL));
while (1)
{
player_move(board, ROW, COL);
ret = is_win(board, ROW, COL);
if (ret != ' ')
break;
display_board(board, ROW, COL);
printf("\n");
computer_move(board, ROW, COL);
ret = is_win(board, ROW, COL);
if (ret != ' ')
break;
display_board(board, ROW, COL);
printf("\n");
}
if (ret == 'X')
{
printf("玩家获胜\n");
}
else if (ret == '0')
{
printf("电脑获胜\n");
}
else if (ret == 'q')
{
printf("平局\n");
}
display_board(board, ROW, COL);
}
int main()
{
int input = 0;
do {
menu();
printf("输入1开始游戏,输入0结束游戏\n");
scanf("%d", &input);
switch (input)
{
case 1:
game();
break;
case 0:
break;
default:
printf("输入错误,请重新输入:\n");
break;
}
} while (input);
return 0;
}