C语言三子棋小游戏的实现
前言
三子棋又叫九宫棋、圈圈叉叉、一条龙、井字棋等。
三子棋游戏规则:三子连成一片即为赢,如果双方都没有连成线,即为平局。
一、如何实现?
1.棋盘大小如何确定?
我们要实现一个3×3的棋盘,就需要定义一个3行3列的数组,但是数组的下标从0开始,玩家选择落子坐标很不方便,所以要定义一个4×4的数组,第0行第0列不使用,如下图红框内的行和列不使用。这样就方便玩家选择落子坐标。
2.如何判定输赢?
三子棋的规则很简单,只要判断每一行、每一列、对角线中是否有连成线的,即为赢。
代码思路:
1、判断是否有相同的行并且不能为空格(数组初始化为空格)。
2、判断是否有相同的列并且不能为空格。
3、判断主次对角线是否相同并且不能为空格。
4、棋盘下满后是否为平局。
代码如下:
//判断谁赢,'X'表示玩家赢,'0'表示电脑赢,'p'表示平局
char IsWin(char map[ROWS][COLS], int row, int col)
{
int i = 0;
int j = 0;
int ret = IsFull(map, ROWS, COLS);
//判断行
for (i = 1; i < row; i++)
{
if (map[i][1] == map[i][2] && map[i][2] == map[i][3] && map[i][1] != ' ')
{
return map[i][1];
}
}
//判断列
for (j = 1; j < col; j++)
{
if (map[1][j] == map[2][j] && map[2][j] == map[3][j] && map[1][j] != ' ')
{
return map[1][j];
}
}
//判断主对角线
if (map[1][1] == map[2][2] && map[2][2] == map[3][3] && map[1][1] != ' ')
{
return map[1][1];
}
//判断次对角线
if (map[1][3] == map[2][2] && map[2][2] == map[3][1] && map[1][3] != ' ')
{
return map[1][3];
}
//判断是否为平局
if (ret == 0)
{
return 'p';
}
else
{
return ' ';//防止编译器报错
}
}
注意:
1、三个值比较时不可以使用连等,==是关系操作符,==是从左到右进行运算的,计算表达式 a == b == c 时,首先会进行逻辑运算 a == b得出逻辑值1或0,得到的结果作为返回值,然后进行逻辑运算 “返回值” == c 得出逻辑值1或0,作为整个表达式的返回值。所以不能这样用。
2、判断完是否平局后,要加一个else,返回一个字符,不然编译器会报错:
因为编译器认为还有一种情况:当所有的if都不满足时,没有返回值,所以要加一个else返回一个对结果没有影响的字符。
二、具体代码实现
1.头文件game.h
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<string.h>
#define ROW 3
#define COL 3
#define ROWS ROW+1
#define COLS COL+1
//初始化棋盘
void InitMap(char map[][COLS], int row, int col);
//打印棋盘
void DisplayMap(char map[][COLS], int row, int col);
//玩家落子
void PlayerMove(char map[][COLS], int row, int col);
//电脑落子
void ComputerMove(char map[][COLS], int row, int col);
//判断棋盘是否满,0表示满,1表示未满
int IsFull(char map[][COLS], int row, int col);
//判断谁赢,'X'表示玩家赢,'0'表示电脑赢,'p'表示平局
char IsWin(char map[][COLS], int row, int col);
2.主函数main.c
#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
void menu()
{
printf("***********************************************\n");
printf("******** 三子棋 *********\n");
printf("***********************************************\n");
printf("*************** 1.play **************\n");
printf("*************** 0.exit **************\n");
printf("***********************************************\n");
}
void game()
{
char map[ROWS][COLS];
char ret = ' ';//用来接收IsWin()的返回值
InitMap(map, ROWS, COLS);//初始化棋盘
DisplayMap(map, ROWS, COLS);//打印棋盘
do
{
PlayerMove(map, ROWS, COLS);//玩家落子
ret = IsWin(map, ROWS, COLS);
if (ret == 'X')
{
printf("玩家赢......\n");
break;
}
else if (ret == 'p')
{
printf("平局......\n");
break;
}
ComputerMove(map, ROWS, COLS);//电脑落子
ret = IsWin(map, ROWS, COLS);
if (ret == '0')
{
printf("电脑赢......\n");
break;
}
}while (IsFull(map,ROWS,COLS));//棋盘已满,结束循环
}
void test()
{
int input = 0;
srand((unsigned)time(NULL));
do
{
menu();
printf("请输入操作代码->");
scanf("%d", &input);
switch (input)
{
case 1:
game();
break;
case 0:
printf("退出游戏成功......\n");
break;
default:
printf("选择错误,请重新输入->\n");
break;
}
} while (input);
}
int main()
{
test();
return 0;
}
3.函数game.c
#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
void InitMap(char map[][COLS], int row, int col)
{
int i = 0;
int j = 0;
for (i = 1; i < row; i++)
{
for (j = 1; j < col; j++)
{
map[i][j] = ' ';
}
}
}
void DisplayMap(char map[][COLS], int row, int col)
{
int i = 0;
int j = 0;
for (i = 1; i < row; i++)
{
for (j = 1; j <= col; j++)
{
printf("%3c",map[i][j]);
if (j < col - 1)
{
printf(" | ");
}
}
printf("\n");
if (i < row - 1)
{
for (j = 1; j < col; j++)
{
printf(" --- ");
}
}
printf("\n");
}
}
void PlayerMove(char map[][COLS], int row, int col)
{
int x = 0;
int y = 0;
printf("玩家走->\n");
while (1)
{
printf("请选择落子坐标->");
scanf("%d %d", &x, &y);
if (x >= 1 && x <= 3 && y >= 1 && y <= 3)
{
if (map[x][y] == ' ')
{
map[x][y] = 'X';
break;//落子成功就跳出循环
}
else
{
printf("该位置已被占用请重新输入->\n");
}
}
else
{
printf("坐标非法,请重新输入......\n");
}
}
DisplayMap(map, ROWS, COLS);
}
void ComputerMove(char map[][COLS], int row, int col)
{
int x = 0;
int y = 0;
printf("电脑走->\n");
while (1)
{
x = rand() % 3 + 1;//1-3
y = rand() % 3 + 1;//1-3
if (map[x][y] == ' ')
{
map[x][y] = '0';
break;
}
}
DisplayMap(map, ROWS, COLS);
}
//判断棋盘是否满,0表示满,1表示未满
int IsFull(char map[][COLS], int row, int col)
{
int i = 0;
int j = 0;
int count = 0;//计算落子过的格子
for (i = 1; i < row; i++)
{
for (j = 1; j < col; j++)
{
if (map[i][j] == 'X' || map[i][j] == '0')
{
count++;
}
}
}
if (count == ROW * COL)
{
return 0;//满
}
else
{
return 1;
}
}
//判断谁赢,'X'表示玩家赢,'0'表示电脑赢,'p'表示平局
char IsWin(char map[ROWS][COLS], int row, int col)
{
int i = 0;
int j = 0;
int ret = IsFull(map, ROWS, COLS);
//判断行
for (i = 1; i < row; i++)
{
if (map[i][1] == map[i][2] && map[i][2] == map[i][3] && map[i][1] != ' ')
{
return map[i][1];
}
}
//判断列
for (j = 1; j < col; j++)
{
if (map[1][j] == map[2][j] && map[2][j] == map[3][j] && map[1][j] != ' ')
{
return map[1][j];
}
}
//判断主对角线
if (map[1][1] == map[2][2] && map[2][2] == map[3][3] && map[1][1] != ' ')
{
return map[1][1];
}
//判断次对角线
if (map[1][3] == map[2][2] && map[2][2] == map[3][1] && map[1][3] != ' ')
{
return map[1][3];
}
//判断是否为平局
if (ret == 0)
{
return 'p';
}
else
{
return ' ';//防止编译器报错
}
}
4、运行结果示例
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
以上是 C语言三子棋小游戏的实现 的全部内容, 来源链接: utcz.com/p/245743.html