1.测试页面的代码
#define _CRT_SECURE_NO_WARNINGS 1
# include<stdio.h>
#include"game.h"
#include<stdlib.h>
#include<time.h>
//菜单
void menu() {
printf("**********欢迎来到三子棋游戏***********\n");
printf("******1.play.**********0.exit.*********\n");
printf("***************************************\n");
}
//游戏
void game() {
char board[ROW][COL] = { 0 };
//初始化棋盘
InitBoard(board, ROW, COL);
//打印棋盘
DisplayBoard(board, ROW, COL);
char ret = 0;
while (1) {
//玩家下棋
PlayerMove(board, ROW, COL);
//判断输赢
ret = Is_Wins(board, ROW, COL);
if (ret != 'C') {//若是不继续游戏则跳出while循环
break;
}
//下完棋打印
DisplayBoard(board, ROW, COL);
//电脑下棋
ComputerMove(board, ROW, COL);
ret = Is_Wins(board, ROW, COL);
if (ret != 'C') {//若是不继续游戏则跳出while循环
break;
}
//下完棋打印
DisplayBoard(board, ROW, COL);
}
//打印出最终结果图
DisplayBoard(board, ROW, COL);
if (ret == '*') {
printf("玩家赢\n");
}
else if (ret == '#') {
printf("电脑赢\n");
}
else if (ret == 'Q') {
printf("平局\n");
}
}
int main() {
int input = 0;
//给电脑下棋的随机性做一个时间戳
srand((unsigned int)time(NULL));
do {
menu();
printf("请输入你的选择:>\n");
scanf("%d", &input);
switch (input) {
case 1:
game();
break;
case 0:
printf("即将退出程序!\n");
exit(0);
break;
default:
printf("输入错误!\n");
break;
}
} while (input);
return 0;
}
2.头文件game.h代码--函数声明
#pragma once
#pragma once
#include<stdio.h>
#define ROW 3
#define COL 3
//初始化棋盘的函数声明
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);
//判断输赢
char Is_Wins(char board[ROW][COL], int row, int col);
3.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] = ' ';
}
}
}
//打印棋盘的函数
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("请输入坐标: ");
scanf("%d %d", &x, &y);
//玩家不懂数组下标从0开始,所以他认为的2 2就是第二行第二个元素,按玩家认知来
if (x >= 1 && x <= row && y >= 1 && y <= col) {
if (board[x - 1][y - 1] == ' ') {//但在表格中要将玩家输入的横纵坐标各减一
board[x - 1][y - 1] = '*';
break;//下棋是回合制游戏,你一下,我一下的,所以输入一步后就停止继续下棋。
}
else {
printf("格子已被占用,请重新输入!\n");
}
}
//若玩家输入的坐标不符合数组内容,例如输入:2 5(数组越界),就会弹出警告,需要重新输入
else {
printf("非法输入坐标\n");
}
}
}
//电脑下棋函数--电脑肯定是知道数组下标为0开始,所以横纵坐标不需要-1
void ComputerMove(char board[ROW][COL], int row, int col) {
int x = 0;
int y = 0;
printf("电脑下棋:>\n");
while (1) {
//给电脑下棋做一个随机性,随便下棋
x = rand() % row;//rand产生0-32767的随机一个数,但%row(3)后随机数的范围在0-2三个数之间
y = rand() % col;//同理
if (board[x][y] == ' ') {
board[x][y] = '#';
break;
}
}
}
//判断棋盘是否满了
int Is_fall(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++) {
if (board[i][j] == ' ') {//说明棋盘没满了
return 0;
}
}
}
return 1;//说明满了,平局
}
//判断输赢
char Is_Wins(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][1] == board[i][2] && board[i][1] != ' ') {
return board[i][1];
}
//列三子连城
if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[1][i] != ' ') {
return board[1][i];
}
}
//正对角线三子连成
if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' ') {
return board[1][1];
}
//副对角线三子连成
if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' ') {
return board[1][1];
}
if (1 == Is_fall(board, ROW, COL)) {
return 'Q';
}
else
return 'C';
}
????????对于井字棋游戏,我们并不陌生,小时候经常与同学,朋友之间玩的一种游戏,它是在一个3*3大小的正方形棋盘中进行,好比五子棋一般,执行回合制,一人走一步,若谁先把下好的棋连成一条线,谁就赢得比赛的胜利。注:这里的一条线指的是某一行,某一列,或者两条对角线上的任意一种达成即可。
????????1.首先,我们可以在主函数中创建一个游戏的基础写法,利用do..while语句可以先执行一次循环体,再进行判断条件,若判断条件一直为真,那么我们便可以一直玩这个游戏。这种写法应该是所有游戏都会用到的写法了。之后我们设计菜单界面,进行游戏界面的美化,输入相应的文字功能,教给用户如何玩这个游戏。
? ? ? ? 2.在game游戏中,根据游戏的核心,创建出一个宏定义的行列矩阵数组,这样做方便我们以后改成5*5,10*10大小的界面时,不需要大费周章改各种数据,只需要修改头文件中define的行列数字即可!然后就该给数组界面建立边界,例:
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ???空格 ?| ?空格 ? | 空格 ? ? ? ?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?空格 ?| ?空格 ? | 空格 ? ? ? ?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?空格 ?| ?空格 ? | 空格 ?
其次,还需要行与行之间建立分割的符合“---”与“|”两种符合
????????????????????????????????????????????????---|---|---
? ? ? ? ? ? ? ????????????????????????????????? ---|---|---? ??
最终形成数组打印后如下:?
????????3. 井字棋作为两方博弈游戏,自然是要创立双方的函数,在这里我使用了玩家(主动操控下棋处的)函数和电脑(计算机下棋)函数,若想玩双人小游戏,则需要将我的电脑函数代码改为玩家函数即可。我设立的规则是玩家使用‘ * '号下棋,电脑使用'#'号下棋,考虑到玩家并不懂数组的下标位置从0开始,所以正常输入,代码中是将玩家输入的坐标行列都减1就行。若是玩家输入的坐标不符合条件,就提示警告;对于电脑函数,就没有那么多的限制,电脑函数的核心在于输入坐标的随机性,函数中用到了rand函数:在0—32767之间产生一个随机数;
?
????????rand函数调用 rand()函数每次调用前都会查询是否调用过srand,是否给srand设定了一个值,如果有那么它会自动调用srand一次来初始化它的起始值. 若之前没有调用srand,那么系统会自动给srand赋初始值,即srand(1)自动调用它一次。
????????想要使rand随机的生成一个随机数就要用到srand函数。
?
?strand函数:设置随机数的起点,让rand()产生的随机数随机化,用时间作种子 srand(time(NULL)),这样每次运行程序的时间肯定是不相同的,产生的随机数肯定就不一样了。代码如下:
srand((unsigned int) time(NULL));//time--时间戳(与系统从1970-0-0 0时0分至今的时间,时时刻刻在变化),增强随机数的随机性(使系统在输出随机数的时候能保持随机性)
? ? ? ?
????????4.接下来就是需要创建判断输赢的函数了。在井字棋中,我设立游戏的输赢方案是在于一方优先达到行三连、列三连、正副对角线三连成线,若是‘ * ’先连成则表明玩家赢,若是‘ # ’号先连成,则是电脑赢,若是棋盘都下满,双方没有分出胜负则表明是平局‘Q’。
1.玩家赢图片展示? ? ? ??
2.电脑赢图片展示
3.平局展示
?
感谢观看,点个关注再走吧谢谢!
|