制作简易三子棋过程分析
本篇具体谈论思路和过程 代码:三子棋整个vs文件(包含源代码) 笔记:三子棋思路分析笔记(可提供下载本文)
一、文件构成
1. test.c
用于游戏主功能的基本框架,包含菜单,游戏棋盘,玩家操作,电脑操作
#pragma once
#include<stdio.h>
#include <stdlib.h>
#include<time.h>
#define ROW 3
#define COL 3
void pieces(char pan[ROW][COL], int row, int col);
void print_pan(char pan[ROW][COL], int row, int col);
void player_move(char pan[ROW][COL], int row, int col);
void cpt_move(char pan[ROW][COL], int row, int col);
char judge(char pan[ROW][COL], int row, int col);
2. game.c
用于游戏功能的实现,框架中功能是如何具体实现,基本为函数
3. game.h
包含实现 game.h 和 test.c 中语句所需要引用的函数
#pragma once
#include<stdio.h>
#include<time.h>
#define ROW 3
#define COL 3
void pieces(char pan[ROW][COL], int row, int col);
void print_pan(char pan[ROW][COL], int row, int col);
void player_move(char pan[ROW][COL], int row, int col);
void cpt_move(char pan[ROW][COL], int row, int col);
char judge(char pan[ROW][COL], int row, int col);
二、实现步骤分析
1. 菜单栏
想要开始游戏必须有 游戏菜单
游戏菜单包含:开始游戏;退出游戏;
实现此过程用switch语句,输入1开始游戏,输入0退出游戏
void menu()
{
printf("__________1.play__________\n");
printf("__________0.exit__________\n");
}
因为希望游戏是可以重复玩的
所以整个游戏必当在一个循环里面
因此选择 do while 循环语句包含整个功能
int main()
{
int input = 0;
do
{
menu();
scanf("%d", &input);
switch (input)
{
case 1:
game();
break;
case 0:
break;
default:
printf("请重新输入正确数字\n");
break;
}
} while (input != 0);
}
2. 准备棋子
初步展现的应该是一个空棋盘
而棋盘中的变数是棋盘中的棋子
这些子由玩家或者电脑下
先将玩家和电脑的棋子准备好,在棋盘中显示是空格是即将下的棋子
void pieces(char pan[ROW][COL], int row, int col)
{
int i = 0;
int j = 0;
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
pan[i][j] = ' ';
}
}
}
这样打印空棋盘的时候直接打印数组就可以了
3. 空棋盘
棋子准备好了,玩家也准备玩了
首先呈现给玩家的是一个空棋盘
将第一、二两行看成一组,一共3组
最后一组和每行的后面需要if语句来改变
test.c代码:
void print_pan(char pan[ROW][COL], int row, int col)
{
int i = 0;
int j = 0;
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
printf(" ");
printf("%c", pan[i][j]);
if (j == (row - 1))
{
printf("\n");
break;
}
printf(" |");
}
if (i == (row - 1))
{
break;
}
for (j = 0; j < col; j++)
{
if (j == (col - 1))
{
printf("---\n");
break;
}
printf("---|");
}
}
printf("--------------------\n");
}
效果:
4. 玩家下棋
需要两个参数代表行和列
但真实的行和列和数组里的行列差1
考虑要素
该坐标是否在棋盘内
该坐标是否已经占用
game.c代码:
void player_move(char pan[ROW][COL], int row, int col)
{
printf("请输入您要下棋的位置:");
int x = 0;
int y = 0;
scanf("%d%d", &x, &y);
while(1)
{
if ((x - 1) > row || (x - 1) < 0 || (y - 1) > col || (y - 1) < 0)
{
printf("该坐标超出棋盘范围,请重新输入:");
scanf("%d%d", &x, &y);
}
else
{
while(pan[x - 1][y - 1] != ' ')
{
printf("该坐标已经占用,请重新输入坐标:");
scanf("%d%d", &x, &y);
}
pan[x - 1][y - 1] = '#';
break;
}
}
printf("玩家下棋:\n");
}
效果:
5. 电脑下棋
由于电脑是自动下棋,首先来看最简单的随机下棋
考虑因素:
生成随机数(包括行和列):通过%控制数字大小,此处不用判断超出棋盘
随机数函数为rand()
需要头文件<time.h>
判断位置有没有棋子
game.c代码:
void cpt_move(char pan[ROW][COL], int row, int col)
{
srand((unsigned)time(NULL));
int x = rand() % row;
int y = rand() % col;
while (1)
{
if(pan[x][y] == ' ')
{
pan[x][y] = '*';
printf("电脑下棋:\n");
break;
}
else
{
x = rand() % row;
y = rand() % col;
}
}
}
效果:
6. 判断胜负
玩家下棋 打印棋盘 判断胜负 电脑下棋 打印棋盘 判断胜负
整个游戏在重复这个过程
所以应当放在一个do while 循环中
其中最重要的是判断胜负的函数
判断胜负函数
考虑因素:
一行/列或者对角线为同一个元素且该元素不为空格
退出循环 宣布胜利方
如果平局,即在棋盘中没有空格
还没下完,即还需要继续对战
game.c代码:
char judge(char pan[ROW][COL], int row, int col)
{
int i = 0;
int j = 0;
for(i = 0; i < row; i++)
{
if ((pan[i][0] == pan[i][1]) && (pan[i][1] == pan[i][2]) && pan[i][0] != ' ')
{
return pan[i][0];
}
}
for (j = 0; j < col; j++)
{
if ((pan[0][j] == pan[1][j]) && (pan[0][j] == pan[2][j]) && pan[0][j] != ' ')
{
return pan[0][j];
}
}
if ((pan[0][0] == pan[1][1]) && (pan[1][1] == pan[2][2]) && pan[1][1] != ' ')
{
return pan[1][1];
}
if ((pan[0][2] == pan[1][1]) && (pan[1][1] == pan[2][0]) && pan[1][1] != ' ')
{
return pan[1][1];
}
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
if (pan[i][j] == ' ')
{
return 'c';
}
}
}
return 'q';
}
效果:
三、test.c文件
进入循环1-打印菜单-获取数字-准备空棋子-打印空棋盘-进入循环2-玩家下棋-判断胜负-电脑下棋-判断胜负-退出循环1-退出循环2
代码:
#define _CRT_SECURE_NO_WARNINGS
#include "game.h"
void menu()
{
printf("--> 1.play\n");
printf("--> 0.exit\n");
printf("请输入您的选择:");
}
void game()
{
char broad[ROW][COL] = { 0 };
pieces(broad, ROW, COL);
print_pan(broad, ROW, COL);
while(1)
{
player_move(broad, ROW, COL);
print_pan(broad, ROW, COL);
if (judge(broad, ROW, COL) != 'c')
{
break;
}
cpt_move(broad, ROW, COL);
print_pan(broad, ROW, COL);
if (judge(broad, ROW, COL) != 'c')
{
break;
}
}
int ret = judge(broad, ROW, COL);
if (ret == '#')
{
printf("恭喜你胜利了\n");
}
else if (ret == '*')
{
printf("很遗憾你输了\n");
}
else
{
printf("平局\n");
}
}
int main()
{
int input = 0;
do
{
menu();
scanf("%d", &input);
printf("--------------------\n");
switch (input)
{
case 1:
game();
break;
case 0:
break;
default:
printf("请重新输入正确数字\n");
break;
}
printf("--------------------\n");
printf("请选择是否重新开始游戏:\n");
} while (input != 0);
}
——————————游戏结束———————————
|