一、三个游戏
1.三子棋
1-1 准备
(人机下棋)函数:
玩家:
1. 初始化棋盘函数
2. 打印棋盘函数
3. 玩家下棋函数
4. 判断输赢函数
...
电脑:
1. 初始化棋盘函数
2. 打印棋盘函数
3. 玩家下棋函数
4. 判断输赢函数
...
1-2 三个文件
game.h:代码声明(函数声明、符号定义)
game.c:代码实现
test.c:测试逻辑
二、三子棋代码
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 = 0; //接收输赢结果
char board[ROW][COL] = { 0 }; //人机对战,玩家下子*,电脑下子#
InitBoard(board,ROW,COL); //初始化棋盘:行列不要固定死 //数组传参
DisplayBoard(board, ROW, COL); //打印棋盘
//下棋:玩家、电脑
while (1)
{
//玩家下棋
PlayerMove(board, ROW, COL); //需要知道行列信息
DisplayBoard(board, ROW, COL); //打印棋盘
//判断输赢
ret = IsWin(board,ROW,COL);
if (ret != 'c')
{
break;
}
//电脑下棋
ComputerMove(board, ROW, COL);
DisplayBoard(board, ROW, COL); //打印棋盘
//判断输赢
ret = IsWin(board, ROW, COL);
if (ret != 'c')
{
break;
}
}
if (ret == '*')
{
printf("玩家赢\n");
}
else if (ret == '#')
{
printf("电脑赢\n");
}
else
{
printf("平局\n");
}
DisplayBoard(board, ROW, COL); //打印游戏结果
}
int main()
{
//设置随机数的生成起点-调用time函数
rand((unsigned int)time(NULL));
//定义变量,接收数据
int input = 0;
do
{
menu(); //打印菜单
printf("请选择:>"); //提示
scanf("%d", &input);
switch (input)
{
case 1:
game();
break;
case 0:
printf("exit\n");
break;
default:
printf("选择错误!请重新选择:0/1\n");
break;
}
} while (input);
return 0;
}
2.game.c(代码实现)
#define _CRT_SECURE_NO_WARNINGS 1
#include "game.h"; //包含头文件
//初始化棋盘
void InitBoard(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++) //列
{
board[i][j] = ' '; //第i行,第j列
}
}
}
/*
第1个版本:列被写死的(3列)
//打印棋盘
void DisplayBoard(char board[ROW][COL], int row, int col)
{
int i = 0;
for (i = 0; i < row; i++)
{
//打印数据
printf(" %c | %c | %c \n",board[i][0],board[i][1],board[i][2]); //列被写死成3列
//打印分割信息
if (i < row - 1)
{
printf("---|---|--- \n");
}
}
}
*/
//2.第2个版本
//打印棋盘
void DisplayBoard(char board[ROW][COL], int row, int col)
{
int i = 0;
for (i = 0; i < row; i++)
{
//打印数据 //有几列打印几组
int j = 0;
for (j = 0; j < col; j++)
{
printf(" %c ",board[i][j]);
//打印|;最后一组打印完数据后,不打印|
if (j < col - 1)
{
printf("|");
}
}
printf("\n");
//打印分割信息
if (i < row - 1)
{
int j = 0;
for (j = 0; j < col; j++)
{
printf("---");
if (j < col - 1)
{
printf("|");
}
}
printf("\n");
}
}
}
//实现玩家下棋
void PlayerMove(char board[ROW][COL], int row, int col)
{
int x = 0; //横坐标
int y = 0; //纵坐标
printf("玩家下棋:>\n");
while (1)
{
printf("请输入坐标:>(x y)\n"); //行列1-3
scanf("%d %d", &x, &y);
//坐标合法范围的判断
if (x >= 1 && x <= row && y >= 1 && y <= col) //输入的坐标合法,行列合法
{
//判断数组是否空格
//注意单个字符空格和*的使用,使用’‘包裹单个字符,不要错误使用“ ”包裹单个字符
if (board[x - 1][y - 1] == ' ') //数组下标从0开始
{
board[x - 1][y - 1] = '*'; //未被占用,可以下棋
break;
}
else
{
printf("坐标被占用,不能下棋,请选择其他位置:>(x y)\n");
}
}
else
{
printf("输入的坐标非法,请重新输入:>(x y)\n");
}
}
}
/*
代码同上>实现玩家下棋(调试问题用)
void PlayerMove(char board[ROW][COL], int row, int col)
{
int x = 0;
int y = 0;
while (1)
{
printf("请输入坐标:(x y)");
scanf("%d %d", &x, &y);
//判断坐标
if (x >= 0 && x <= row && y >= 0 && y <= row) //合法坐标
{
if (board[x - 1][y - 1] == ' ')
{
board[x - 1][y - 1] = '*';
break;
}
else
{
printf("坐标占用,重新输入\n");
}
}
else
{
printf("非法\n");
}
}
}
*/
//实现电脑下棋
void ComputerMove(char board[ROW][COL], int row, int col)
{
printf("电脑下棋:>");
int x = 0;
int y = 0;
//生成随机数0~row-1,0~col-1
x = rand() % row;
y = rand() % col;
while (1)
{
//判断坐标是否被占用
if (board[x][y] == ' ')
{
board[x][y] = '#';
break;
}
else
{
printf("坐标被占用,请重新输入:>(x y)\n");
}
}
}
//实现平
//满了返回1,不满返回0
int IsFull(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;
}
//实现赢
char IsWin(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][2] && board[i][1] != ' ')
{
return board[i][1]; //返回该行任意一个元素就行
}
}
//再判断列
int j = 0;
for (j = 0; j < col; j++)
{
//一列的三个相等且该列任何一个都不等于空格
if (board[0][j] == board[1][j] == board[2][j] && board[1][j] != ' ')
{
return board[1][j]; //返回该列任意一个元素就行
}
}
//最后看斜向(2条对角线)
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(IsFull(board,row,col)) //传递行列参数
{
return 'q'; //平局return q
}
//游戏继续
//未分出胜负,也不是平局
return 'c';
}
3.game.h(代码声明)
#pragma once
//可根据需要的棋盘大小更改行列数
#define ROW 3 //定义行
#define COL 3 //定义列
#include <stdio.h>
//引入rand函数和time函数头文件
#include <stdlib.h>
#include <time.h>
//初始化棋盘
void InitBoard(char board[ROW][COL], int row, int col);
//打印棋盘
void DisplayBoard(char board[ROW][COL], int row, int col);
//玩家下棋
void PlayerMove(char board[ROW][COL],int row,int col);
//电脑下棋
//找空白位置随机下棋
void ComputerMove(char board[ROW][COL], int row, int col);
//判断输赢:胜平负,继续4种状态
//1.玩家赢-*
//2.电脑赢-#
//3.平局-q
//4.继续下棋-c
char IsWin(char board[ROW][COL], int row,int col);
三、三子棋实现
四、扫雷游戏
1.准备
2个数组
1个存放布置的雷的信息:
1. char mine[9][9];
2. 初始化为 ' 0 '
3. 判断坐标的合法性(防止越界):
增加一圈(增加了两列、两行)
char mine[11][11];
1个存放排查出来的雷的信息:
char show[9][9];
初始化为 ' * '
2.扫雷源文件
2.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 mine[ROWS][COLS] = { 0 }; //存放布置的雷的信息
char show[ROWS][COLS] = { 0 }; //存放排查出来的雷的信息
//初始化数组的内容为指定内容
//mine数组在未布置雷之前都是’0‘
InitBoard(mine, ROWS, COLS,'0');
//show数组在未排查雷之前都是’*‘
InitBoard(show, ROWS, COLS,'*');
//打印
DisplayBoard(mine,ROW,COL); //不排雷之后不打印
DisplayBoard(show, ROW, COL);
//埋雷
//SetMine(mine,ROW,COL); //埋到9*9的格子中
//排查雷
}
int main()
{
//设置随机数生成起点
srand((unsigned int)time(NULL));
int input = 0;
do
{
menu();
printf("请选择:>1/0 \n");
scanf("%d", &input);
switch (input)
{
case 1:
game();
break;
case 0:
break;
default:
printf("选择错误,请重新选择:>1/0 \n");
}
}while(input);
return 0;
}
2.2 game.c
#define _CRT_SECURE_NO_WARNINGS 1
#include "game.h"
void InitBoard(char board[ROWS][COLS], int rows, int cols,char set)
{
int i = 0;
int j = 0;
for (i = 0; i < rows; i++)
{
for (j = 0; j < cols; j++)
{
board[i][j] = set;
}
}
}
void DisplayBoard(char board[ROWS][COLS], int row, int col)
{
int i = 0;
int j = 0;
printf("***************扫雷*************\n");
for (j = 0; j <= col; j++)
{
printf("%d ",j );
}
printf("\n");
for (i = 1; i <= row; i++)
{
printf("%d ", i); //打印行号
for (j = 1; j <= col; j++)
{
printf("%c ", board[i][j]);
}
printf("\n");
}
printf("***************扫雷*************\n");
}
//实现埋雷
void SetMine(char board[ROWS][COLS], int row, int col)
{
//确定雷的数量
int count = EASY_COUNT;
//埋雷
while (count)
{
//横坐标
int x = rand() % row + 1;
//纵坐标
int y = rand() % col + 1;
//判断是否已经埋雷:1-已埋雷,0-无
if (board[x][y] == '0')
{
board[x][y] = '1';
count--; //
}
}
}
2.3 game.h
#pragma once
#include <stdio.h>
//为使用srand()函数引用
#include <stdlib.h>
#include "time.h"
//9行9列
#define ROW 9
#define COL 9
//11行11列
#define ROWS ROW+2
#define COLS COL+2
//可更改埋雷数量
#define EASY_COUNT
void InitBoard(char board[ROWS][COLS], int rows, int cols,char set); //大小写区分形参名和定义的符号
void DisplayBoard(char board[ROWS][COLS], int row, int col);
void SetMine(char board[ROWS][COLS], int row, int col);