目录
在实现我们的“三子棋”小游戏之前,先让我们简单的学习一下数组吧
数组
数组:是一组相同类型元素的集合
数组有一维数组和二维数组
数组的创建:
注:数组创建,在C99标准之前, [] 中要给一个常量才可以,不能使用变量。在C99标准支持了变长数
组的概念,数组的大小可以使用变量指定,但是数组不能初始化。数组初始化:
数组的初始化是指,在创建数组的同时给数组的内容一些合理初始值(初始化)。
数组的使用:
1. 数组是使用下标来访问的,下标是从0开始。
2. 数组的大小可以通过计算得到。数组名是什么呢?
数组名是数组首元素的地址
但是有2个例外:
1. sizeof(数组名),这里的数组名是表示整个数组,计算的是整个数组的大小,单位是字节
2. &数组名,这里的数组名是表示整个数组,&数组名取出的是数组的地址
数组在内存中的存储:
数组在内存中的存储是由低地址到高地址连续存放的
二维数组可以看成由n个一维数组来存放的,所以二维数组在内存的存储也是连续存放的
在简单的认识了数组后,就让我们开始本文的正题,开发一个三子棋的小游戏吧
三子棋
预想的效果:
一个简单的人机对战三子棋的游戏,玩家靠输入坐标来控制下子的位置。
大体思路:
1.一个游戏菜单,开始和退出
2.打印一个3*3的棋盘
3.玩家下子
4.电脑下子
5.判断输赢
6.清屏,重新一局
现在让我们按步骤一步步来实现,一个项目分节完成
为了使主函数不过于复杂,我们采用模块化编程
第一步:打印一个简单的游戏菜单
1.输出一个简易菜单,可以通过1/0来进行选择,输入1开始,0退出,非1,0提示 输入错误,并可以多次的进行游戏,输入错误可以重新输入。
代码实现:打印菜单
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
void Checkers_menu()
{
printf("*********************\n");
printf("*** 1. play ***\n");
printf("*** 0. exit ***\n");
printf("*********************\n");
}
void test()
{
int a = 0;
Checkers_menu();
do
{
printf("请选择:");
scanf("%d", &a);
switch (a)
{
case 1:
game(); break;
case 0:
printf("退出游戏\n"); break;
default :
printf("输入错误\n"); break;
}
} while (a);
}
int main()
{
test();
return 0;
}
第二步:简易的菜单打印出来后,我们就需要封装一个game函数来实现我们玩游戏的过程。
当我们选择1后,就要开始玩游戏了。游戏开始首先我们需要将棋盘打印出来,先看看我们预期的棋盘效果
一个简单的井字棋盘,我们会发现这就是一个由3行3列的二维数组来实现的。在打印棋盘之前我们先将棋盘进行初始化,之后在进行打印
代码我们采用的模块化编程,我们将游戏的这部分单独封装在一个game函数中
代码实现:打印棋盘
//初始化棋盘
void Checkers_Init(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++)
{
board[i][j] = ' ';
}
}
}
//打印棋盘
void Checkers_print(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)
{
for (j = 0; j < col; j++)
{
printf("---");
if (j < col - 1)
printf("|");
}
printf("\n");
}
}
}
第三步:棋盘打印出来后,我们就要来进行玩家和电脑的下子了
玩家的下子其实就是通过二维数组的下标来控制,电脑的下子我们采用的是随机值来确定下子动作。当我们输入的坐标被占用时提示非法占用。这里我们一样通过两个函数来实现
代码实现: 人机出棋
//玩家下下棋
void Checkers_player(char board[ROW][COL], int row, int col)
{
int i = 0;
int j = 0;
while (1)
{
printf("请玩家出棋:");
scanf("%d %d", &i, &j);
if (i > 0 && i <= row && j>0 && j <= col)
{
if (board[i - 1][j - 1] == ' ')
{
board[i - 1][j - 1] = '*';
break;
}
else
{
printf("非法占用\n");
}
}
else
printf("非法超出范围\n");
}
}
//电脑下棋
void Checkers_computer(char board[ROW][COL], int row, int col)
{
printf("电脑出棋:\n");
if (is_full(board, row, col) == 0)
{
while (1)
{
int i = rand() % row;
int j = rand() % col;
if (board[i][j] == ' ')
{
board[i][j] = '#';
break;
}
}
}
}
第四步:一个游戏最主要结局就是一个判断输赢
我们通过一个函数来判断是谁赢了,定义返回值:玩家赢返回*,电脑赢返回#,平局返回Q,继续返回C。要认定平局我们也要一个函数来判断是不是满棋。
代码实现:判断输赢
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;
}
//判断谁赢
char is_win(char board[ROW][COL], int row, int col)
{
//判断行
int i = 0;
int j = 0;
for (i = 0; i < row; i++)
{
if (board[i][0] == board[i][1] && board[i][1] == board[i][2])
{
return board[i][0];
}
}
//判断列
for (j = 0; j < col; j++)
{
if (board[0][j] == board[1][j] && board[1][j] == board[2][j])
{
return board[0][j];
}
}
//判断对角线
if (board[0][0] == board[1][1] && board[1][1] == board[2][2])
{
return board[1][1];
}
if (board[0][2] == board[1][1] && board[1][1] == board[2][0])
{
return board[1][1];
}
//判断平局
if (is_full(board, row, col) == 1)
{
return 'Q';
}
else
return 'C';
}
每个部分的函数我们就封装完成了,在game函数里进行调整
整体代码:三子棋
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#define ROW 3
#define COL 3
//初始化棋盘
void Checkers_Init(char board[ROW][COL], int row, int col);
//打印棋盘
void Checkers_print(char board[ROW][COL], int row, int col);
//玩家下棋
void Checkers_player(char board[ROW][COL], int row, int col);
//电脑下棋
void Checkers_computer(char board[ROW][COL], int row, int col);
//判断谁赢
char is_win(char board[ROW][COL], int row, int col);
void Checkers_menu()
{
printf("**************************\n");
printf("***** 1. play *****\n");
printf("***** 0. exit *****\n");
printf("**************************\n");
}
void game()
{
char board[ROW][COL];
char ret = 0;
Checkers_Init(board, ROW, COL);
Checkers_print(board, ROW, COL);
while (1)
{
Checkers_player(board, ROW, COL);
Checkers_print(board, ROW, COL);
Checkers_computer(board, ROW, COL);
Checkers_print(board, ROW, COL);
ret=is_win(board,ROW,COL);
if (ret == '*')
{
printf("玩家赢了\n");
break;
}
else if (ret == '#')
{
printf("电脑赢了\n");
break;
}
else if(ret=='Q')
{
printf("平局\n");
break;
}
}
}
void test()
{
int a = 0;
srand((unsigned int )time(NULL));
do
{
Checkers_menu();
printf("请选择:");
scanf("%d", &a);
switch (a)
{
case 1:
game(); break;
case 0:
printf("退出游戏\n"); break;
default:
printf("输入错误\n"); break;
}
} while (a);
}
int main()
{
test();
return 0;
}
//初始化棋盘
void Checkers_Init(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++)
{
board[i][j] = ' ';
}
}
}
//打印棋盘
void Checkers_print(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)
{
for (j = 0; j < col; j++)
{
printf("---");
if (j < col - 1)
printf("|");
}
printf("\n");
}
}
}
//玩家下下棋
void Checkers_player(char board[ROW][COL], int row, int col)
{
int i = 0;
int j = 0;
while (1)
{
printf("请玩家出棋:");
scanf("%d %d", &i, &j);
if (i > 0 && i <= row && j > 0 && j <= col)
{
if (board[i - 1][j - 1] == ' ')
{
board[i - 1][j - 1] = '*';
break;
}
else
{
printf("非法占用\n");
}
}
else
printf("非法超出范围\n");
}
}
//电脑下棋
void Checkers_computer(char board[ROW][COL], int row, int col)
{
printf("电脑出棋:\n");
if (is_full(board, row, col) == 0)
{
while (1)
{
int i = rand() % row;
int j = rand() % col;
if (board[i][j] == ' ')
{
board[i][j] = '#';
break;
}
}
}
}
//判断是否满盘
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;
}
//判断谁赢
char is_win(char board[ROW][COL], int row, int col)
{
//判断行
int i = 0;
int j = 0;
for (i = 0; i < row; i++)
{
if (board[i][0] == board[i][1] && board[i][1] == board[i][2])
{
return board[i][0];
}
}
//判断列
for (j = 0; j < col; j++)
{
if (board[0][j] == board[1][j] && board[1][j] == board[2][j])
{
return board[0][j];
}
}
//判断对角线
if (board[0][0] == board[1][1] && board[1][1] == board[2][2])
{
return board[1][1];
}
if (board[0][2] == board[1][1] && board[1][1] == board[2][0])
{
return board[1][1];
}
//判断平局
if (is_full(board, row, col) == 1)
{
return 'Q';
}
else
return 'C';
}
三子棋部分没有整理思路,希望过段时间的我自己能看懂。哈哈哈哈