目录
前言
实现这样一个代码程序,其实并不算太难,所需要的知识量概括为,数组,函数,循环语句,分支语句。在这之中想必最为复杂的就是判断是否获胜了吧。
废话不多说,让我们开始吧。
1、 game_tic.h
game_tic.h : 自定义头文件,主要用于:
1 . 库函数的包含2 . 自定义函数的申明
3 . 定义棋盘大小
#ifndef GAME_TIC_H
#define GAME_TIC_H
//棋盘大小
#define ROW 15
#define COL 15
//方便计算用
#define ROWS (ROW + 1)
#define COLS (COL + 1)
//防止用数组检索的时候,出现非法访问
#define ROWSS (ROWS + 1)
#define COLSS (COLS + 1)
#define NUM 5// 确定n子棋
//包含的头文件
#include <stdio.h>
#include <windows.h>
#include <time.h>
#include <stdlib.h>
//函数声明
void game_tic();
void InitBoard(char board[ROWSS][COLSS]);
void PrintBoard(char board[ROWSS][COLSS]);
void PlayerMove(char board[ROWSS][COLSS], int PlayerMark[2], char p1);
void ComputerMove(char board[ROWSS][COLSS], int computmark[2], char p2);
char IsWin(char board[ROWSS][COLSS], int x, int y, char el);
#endif
2、 test.c
test.c : 用于实现大致界面
#include "game_tic.h"
void menu()
{
int input = 0;
do
{
printf("********************************\n");
printf("****** 0.返回 *******\n");
printf("****** 1. n子棋游戏 *******\n");
printf("****** 2.(还没想好) *******\n");
printf("********************************\n");
printf("请选择 >: ");
scanf("%d", &input);
switch (input)
{
case 1:
game_tic();
break;
default:
system("cls");
printf("输入错误,请从新输入\n");
break;
}
} while (input);
}
void start()//选择开始菜单
{
int input = 0;
do
{
printf("************************\n");
printf("****** 1.开始游戏 ****\n");
printf("****** 0.退出程序 ****\n");
printf("************************\n");
printf("请输入 >: ");
scanf("%d", &input);
if (input == 1)
{
menu();
}
else if (input != 0)
{
printf("输入错误,请从新输入\n");
system("cls");//清屏
}
} while (input);
}
int main()
{
start();
return 0;
}
3 、 game_tic.c
game_tic.c : 用于实现游戏内容
3.1 游戏主体
因为数组在进行传参的时候传的是首元素地址,数组在使用其它函数的时候不会想形参一样进行销毁,所以我们可以引用一个数组来保存坐标。
注意:
ComputMark[2] = { 0 }; 用于记录电脑坐标
PlayerMark[2] = { 0 }; 用于记录玩家坐标
此做法在本程序内起到关键作用
//游戏主体
void game_tic()
{
srand((unsigned int)time(NULL));
int x = 0;
int y = 0;
char board[ROWSS][COLSS] = { 0 };
int ComputMark[2] = { 0 };//记录电脑的坐标
int PlayerMark[2] = { 0 };//记录玩家的坐标
InitBoard(board);
PrintBoard(board);
while (1)
{
PlayerMove(board, PlayerMark, '*');
PrintBoard(board);
x = PlayerMark[0];
y = PlayerMark[1];
if ('*' == IsWin(board, x, y, '*'))
{
printf("玩家获胜\n");
break;
}
if (IsFull(board))
{
printf("平局\n");
break;
}
ComputerMove(board, ComputMark,'#');
PrintBoard(board);
x = ComputMark[0];
y = ComputMark[1];
if ('#' == IsWin(board, x, y, '#'))
{
printf("电脑获胜\n");
break;
}
if (IsFull(board))
{
printf("平局\n");
break;
}
}
}
3.2 游戏的具体实现
3.2.1 打印棋盘
void PrintBoard(char board[ROWSS][COLSS])
{
int i = 0;
int j = 0;
system("cls");
for (i = 1; i < ROWS; i++)//打印横坐标
{
printf("%4d", i);
}
printf("\n");
for (i = 1; i < ROWS; i++)
{
printf("%-2d", i);//打印列坐标
for (j = 1; j < COLS; j++)
{
printf(" %c ", board[i][j]);
if(j != COLS - 1)
printf("|");
}
printf("\n ");
for (j = 1; j < COLS && i < ROWS - 1; j++)
{
printf("----");
}
printf("\n");
}
}
效果图展示:
ROW 为 3,COL 为 3 的时候 (三子棋棋盘)
ROW 为 15,COL 为 15 的时候 (五子棋棋盘)
3.2.2 初始化棋盘
在每次进行游戏之前需要对棋盘进行初始化,即里面元素全放 空格 。
void InitBoard(char board[ROWSS][COLSS])
{
int i = 0;
int j = 0;
for (i = 0; i < ROWSS; i++)
{
for (j = 0; j < COLSS; j++)
{
board[i][j] = ' ';
}
}
}
3.2.3 玩家进行下棋
在接收到一个可用坐标时,将其记录在数组内
注意:
如果想实现 玩家 VS 玩家 ,可以将 电脑下棋 改为 玩家下棋
void PlayerMove(char board[ROWSS][COLSS],int PlayerMark[2], char p1)
{
int x = 0;
int y = 0;
while (1)
{
printf("请输入坐标 (x,y)");
scanf("%d,%d", &x, &y);
if (x > 0 && x < COLSS && y > 0 && y < ROWSS)
{
if (board[y][x] == ' ')
{
board[y][x] = p1;
break;
}
else
{
printf("输入的坐标已被占用,请从新输入\n");
}
}
else
{
printf("非法输入坐标,请从新输入\n");
}
}
PlayerMark[0] = x;
PlayerMark[1] = y;
}
3.2.4 电脑下棋
电脑下棋的时候,我使用了 rand( ) 函数进行随机取值
如果想了解函数的用法请参考 :http://cplusplus.com/reference/cstdlib/rand/?kw=rand
void ComputerMove(char board[ROWSS][COLSS], int computmark[2], char p2)
{
while (1)
{
int x = rand() % COL + 1;
int y = rand() % ROW + 1;
computmark[0] = x;
computmark[1] = y;
if (board[y][x] == ' ')
{
board[y][x] = p2;
break;
}
}
}
3.2.5 判断是否获胜
IsCount : 返回当前下棋坐标周围的棋子数量
char IsWin(char board[ROWSS][COLSS],int x, int y, char el)
{
//继续 返回 'C'
//获胜 返回 e1
if (NUM == IsCount(board, x, y))
{
return el;
}
else
{
return 'C';
}
}
思路:
落下一个棋子,记录它的坐标,然后向4个方向去寻找相同的棋子并记录数量,用一个数组去存储每个方向的棋子数量,取最大值返回毕竟也不能保证不会出现这样的情况
//计数
int IsCount(char board[ROWSS][COLSS], int x, int y)
{
int i = 0;
int moveX = x;
int moveY = y;
int count = 1;//计数
int countmax = 0;//4个方向上的最多棋子数量
int countarr[4] = { 0 };//记录 4 个方向上的棋子数量
// [0] 为左上斜
// [1] 为右上斜
// [2] 为竖
// [3] 为横
//左上斜
if (board[moveY + 1][moveX - 1] == board[moveY][moveX] ||
board[moveY - 1][moveX + 1] == board[moveY][moveX])
{
count = 1;
//左上角
for (i = 0, moveX = x, moveY = y;
board[moveY + 1][moveX - 1] == board[moveY][moveX] && i < NUM
; i++)
{
count++;
moveX += 1;
moveY -= 1;
}
//右下角
for (i = 0, moveX = x, moveY = y;
board[moveY - 1][moveX + 1] == board[moveY][moveX] && i < NUM
; i++)
{
count++;
moveX += 1;
moveY -= 1;
}
countarr[0] = count;
moveX = x;
moveY = y;
}
//右上斜
if (board[moveY - 1][moveX - 1] == board[moveY][moveX] ||
board[moveY + 1][moveX + 1] == board[moveY][moveX])
{
count = 1;
for (i = 0, moveX = x, moveY = y;
board[moveY - 1][moveX - 1] == board[moveY][moveX] && i < NUM
; i++)
{
count++;
moveX -= 1;
moveY -= 1;
}
for (i = 0, moveX = x, moveY = y;
board[moveY + 1][moveX + 1] == board[moveY][moveX] && i < NUM
; i++)
{
count++;
moveX += 1;
moveY += 1;
}
countarr[1] = count;
moveX = x;
moveY = y;
}
//竖
if (board[moveY][moveX] == board[moveY + 1][moveX] ||
board[moveY][moveX] == board[moveY - 1][moveX])
{
count = 1;
//向上计数
for (i = 0, moveX = x, moveY = y; (moveY + 1 <= ROW) && i < NUM &&
(board[moveY][moveX] == board[moveY + 1][moveX])
; i++)
{
count++;
moveY += 1;
}
for (i = 0, moveX = x, moveY = y; (moveY - 1 >= 0) && i < NUM &&
(board[moveY][moveX] == board[moveY - 1][moveX])
; i++)
{
count++;
moveY -= 1;
}
countarr[2] = count;
moveX = x;
moveY = y;
}
//横
if (board[moveY][moveX] == board[moveY][moveX + 1] ||
board[moveY][moveX] == board[moveY][moveX - 1])
{
count = 1;
for (i = 0, moveX = x,moveY = y; (moveX + 1 <= COL) && i < NUM &&
(board[moveY][moveX] == board[moveY][moveX + 1])
; i++)
{
count++;
moveX += 1;
}
for (i = 0, moveX = x, moveY = y; (moveX - 1 >= 0) && i < NUM &&
(board[moveY][moveX] == board[moveY][moveX - 1])
; i++)
{
count++;
moveX -= 1;
}
countarr[3] = count;
}
countmax = arrmax(countarr);
return countmax;
}
//判断4个方向里的棋子数量的最大值
int arrmax(int arr[4])
{
int i = 0;
int max = arr[0];
for (i = 1; i < 4; i++)
{
if (arr[i] > max)
{
max = arr[i];
}
}
return max;
}
3.2.6 判断棋盘是否已经满
若棋盘已满,还没有分出胜负,则退出游戏,按平局处理
int IsFull(char board[ROWSS][COLSS])
{
int i = 0;
int j = 0;
for (i = 1; i < ROWS; i++)
{
for (j = 1; j < COLS; j++)
{
if (board[i][j] == ' ')
return 0;
}
}
return 1;
}
4、代码展示
4.1 game_tic.h
#ifndef GAME_TIC_H
#define GAME_TIC_H
//棋盘大小
#define ROW 15
#define COL 15
#define ROWS (ROW + 1)
#define COLS (COL + 1)
#define ROWSS (ROWS + 1)
#define COLSS (COLS + 1)
#define NUM 5// 确定n子棋
//包含的头文件
#include <stdio.h>
#include <windows.h>
#include <time.h>
#include <stdlib.h>
//函数声明
void game_tic();
void InitBoard(char board[ROWSS][COLSS]);
void PrintBoard(char board[ROWSS][COLSS]);
void PlayerMove(char board[ROWSS][COLSS], int PlayerMark[2], char p1);
void ComputerMove(char board[ROWSS][COLSS], int computmark[2], char p2);
char IsWin(char board[ROWSS][COLSS], int x, int y, char el);
#endif
4.2 test.c
#include "game_tic.h"
void menu()
{
int input = 0;
do
{
printf("********************************\n");
printf("****** 0.返回 *******\n");
printf("****** 1. n子棋游戏 *******\n");
printf("****** 2.(还没想好) *******\n");
printf("********************************\n");
printf("请选择 >: ");
scanf("%d", &input);
switch (input)
{
case 1:
game_tic();
break;
default:
system("cls");
printf("输入错误,请从新输入\n");
break;
}
} while (input);
}
void start()//选择开始菜单
{
int input = 0;
do
{
printf("************************\n");
printf("****** 1.开始游戏 ****\n");
printf("****** 0.退出程序 ****\n");
printf("************************\n");
printf("请输入 >: ");
scanf("%d", &input);
if (input == 1)
{
menu();
}
else if (input != 0)
{
printf("输入错误,请从新输入\n");
system("cls");//清屏
}
} while (input);
}
int main()
{
start();
return 0;
}
4.3 game_tic.c
#include "game_tic.h"
//判断棋盘是否满
int IsFull(char board[ROWSS][COLSS])
{
int i = 0;
int j = 0;
for (i = 1; i < ROWS; i++)
{
for (j = 1; j < COLS; j++)
{
if (board[i][j] == ' ')
return 0;
}
}
return 1;
}
int arrmax(int arr[4])
{
int i = 0;
int max = arr[0];
for (i = 1; i < 4; i++)
{
if (arr[i] > max)
{
max = arr[i];
}
}
return max;
}
//计数
int IsCount(char board[ROWSS][COLSS], int x, int y)
{
int i = 0;
int moveX = x;
int moveY = y;
int count = 1;//计数
int countmax = 0;//4个方向上的最多棋子数量
int countarr[4] = { 0 };//记录 4 个方向上的棋子数量
// [0] 为左上斜
// [1] 为右上斜
// [2] 为竖
// [3] 为横
//左上斜
if (board[moveY + 1][moveX - 1] == board[moveY][moveX] ||
board[moveY - 1][moveX + 1] == board[moveY][moveX])
{
count = 1;
//左上角
for (i = 0, moveX = x, moveY = y;
board[moveY + 1][moveX - 1] == board[moveY][moveX] && i < NUM
; i++)
{
count++;
moveX += 1;
moveY -= 1;
}
//右下角
for (i = 0, moveX = x, moveY = y;
board[moveY - 1][moveX + 1] == board[moveY][moveX] && i < NUM
; i++)
{
count++;
moveX += 1;
moveY -= 1;
}
countarr[0] = count;
moveX = x;
moveY = y;
}
//右上斜
if (board[moveY - 1][moveX - 1] == board[moveY][moveX] ||
board[moveY + 1][moveX + 1] == board[moveY][moveX])
{
count = 1;
for (i = 0, moveX = x, moveY = y;
board[moveY - 1][moveX - 1] == board[moveY][moveX] && i < NUM
; i++)
{
count++;
moveX -= 1;
moveY -= 1;
}
for (i = 0, moveX = x, moveY = y;
board[moveY + 1][moveX + 1] == board[moveY][moveX] && i < NUM
; i++)
{
count++;
moveX += 1;
moveY += 1;
}
countarr[1] = count;
moveX = x;
moveY = y;
}
//竖
if (board[moveY][moveX] == board[moveY + 1][moveX] ||
board[moveY][moveX] == board[moveY - 1][moveX])
{
count = 1;
//向上计数
for (i = 0, moveX = x, moveY = y; (moveY + 1 <= ROW) && i < NUM &&
(board[moveY][moveX] == board[moveY + 1][moveX])
; i++)
{
count++;
moveY += 1;
}
for (i = 0, moveX = x, moveY = y; (moveY - 1 >= 0) && i < NUM &&
(board[moveY][moveX] == board[moveY - 1][moveX])
; i++)
{
count++;
moveY -= 1;
}
countarr[2] = count;
moveX = x;
moveY = y;
}
//横
if (board[moveY][moveX] == board[moveY][moveX + 1] ||
board[moveY][moveX] == board[moveY][moveX - 1])
{
count = 1;
for (i = 0, moveX = x,moveY = y; (moveX + 1 <= COL) && i < NUM &&
(board[moveY][moveX] == board[moveY][moveX + 1])
; i++)
{
count++;
moveX += 1;
}
for (i = 0, moveX = x, moveY = y; (moveX - 1 >= 0) && i < NUM &&
(board[moveY][moveX] == board[moveY][moveX - 1])
; i++)
{
count++;
moveX -= 1;
}
countarr[3] = count;
}
countmax = arrmax(countarr);
return countmax;
}
char IsWin(char board[ROWSS][COLSS],int x, int y, char el)
{
//继续 返回 'C'
//获胜 返回 e1
if (NUM == IsCount(board, x, y))
{
return el;
}
else
{
return 'C';
}
}
//电脑 游玩
void ComputerMove(char board[ROWSS][COLSS], int computmark[2], char p2)
{
while (1)
{
int x = rand() % COL + 1;
int y = rand() % ROW + 1;
computmark[0] = x;
computmark[1] = y;
if (board[y][x] == ' ')
{
board[y][x] = p2;
break;
}
}
}
// 玩家 游玩
void PlayerMove(char board[ROWSS][COLSS],int PlayerMark[2], char p1)
{
int x = 0;
int y = 0;
while (1)
{
printf("请输入坐标 (x,y)");
scanf("%d,%d", &x, &y);
if (x > 0 && x < COLSS && y > 0 && y < ROWSS)
{
if (board[y][x] == ' ')
{
board[y][x] = p1;
break;
}
else
{
printf("输入的坐标已被占用,请从新输入\n");
}
}
else
{
printf("非法输入坐标,请从新输入\n");
}
}
PlayerMark[0] = x;
PlayerMark[1] = y;
}
//初始化棋盘
void InitBoard(char board[ROWSS][COLSS])
{
int i = 0;
int j = 0;
for (i = 0; i < ROWSS; i++)
{
for (j = 0; j < COLSS; j++)
{
board[i][j] = ' ';
}
}
}
//打印棋盘
void PrintBoard(char board[ROWSS][COLSS])
{
int i = 0;
int j = 0;
system("cls");
for (i = 1; i < ROWS; i++)//打印横坐标
{
printf("%4d", i);
}
printf("\n");
for (i = 1; i < ROWS; i++)
{
printf("%-2d", i);//打印列坐标
for (j = 1; j < COLS; j++)
{
printf(" %c ", board[i][j]);
if(j != COLS - 1)
printf("|");
}
printf("\n ");
for (j = 1; j < COLS && i < ROWS - 1; j++)
{
printf("----");
}
printf("\n");
}
}
//游戏主体
void game_tic()
{
srand((unsigned int)time(NULL));
int x = 0;
int y = 0;
char board[ROWSS][COLSS] = { 0 };
int ComputMark[2] = { 0 };
int PlayerMark[2] = { 0 };
InitBoard(board);
PrintBoard(board);
while (1)
{
PlayerMove(board, PlayerMark, '*');
PrintBoard(board);
x = PlayerMark[0];
y = PlayerMark[1];
if ('*' == IsWin(board, x, y, '*'))
{
printf("玩家获胜\n");
break;
}
if (IsFull(board))
{
printf("平局\n");
break;
}
ComputerMove(board, ComputMark,'#');
PrintBoard(board);
x = ComputMark[0];
y = ComputMark[1];
if ('#' == IsWin(board, x, y, '#'))
{
printf("电脑获胜\n");
break;
}
if (IsFull(board))
{
printf("平局\n");
break;
}
}
}
5、一定要看这里
既然你都看到这里了
如果对你右帮助或者觉得好的话,请给一个赞φ(゜▽゜*)♪
如果喜欢作者或者想看更多内容的话,请点一下关注(´▽`ʃ♡ƪ)
如果你怕找不到这篇博客,有一个放走丢的办法,看到那个星星了吗,点一下有惊喜哦
咱也不是是说特别想要 ,就是想请您可怜可怜这位卑微的博主吧