我还会再遇到ta。
所以,这并不算是真正意义上得离别。
虽然从近几个月几乎每天都跟ta走的颇近。每次得相遇都会让我恍惚。
我想躲着ta的一些,但是每次提起思绪却总会跟ta不期而遇。
遇时苦恼,别时着迷。
昨日又与ta相遇,这一聚,就是六个多时辰。从正午窗外得鸣笛到回头时到卷闸门刺耳的伸展,我才想起跟一碗炸酱面不见不散得约定。
跟后者比起来,离别带给我的,更是精神食粮。
好了ta就是BUG
实现了三子棋后,这一离别才显得更有意义。理解和实现差之千里,编程就是这样。对于实现入门三子棋可能是大同小异的,但是我在内部加入了标签,让这个小程序变得更加意义深刻,同时一记与BUG的不解之缘。
实现:
首先应该想到使用函数来使分工简洁明确
菜单,游戏功能。
菜单:
main函数中设定menu()函数来打印菜单 即 开始游戏和退出游戏,使用do while语句来调用游戏功能game()函数。实现完整的互动。
对于游戏内部功能game()而言,设置
1 初始化棋盘 (空格和外观)2 打印棋盘 (每次下棋后进行结果显示)3 用户下棋 4 电脑随机下棋
5 输赢判断 6 平局判断
这么多函数都放在一个源文件显然是酸辣的,所以我们定义一个实现游戏的头文件”threechess.h“进行函数的声明,后编写定义他们的源文件”threechess.c".
第一步:先在main函数中讲函数流程实现
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include"threechess.h"
#include<Windows.h>
#include<time.h>
void menu()
{
printf("*******************************************\n");
printf("------ 我可以大口吞下玻璃而不伤身体--------\n"); //label 1. original test.
printf("------1. 开始游戏-------------------------\n");
printf("------0. 退出游戏-------------------------\n");
printf("*******************************************\n");
};void game();
int main()
{
menu();
int a = 0;
do
{
assert(scanf("%d", &a));//防止用户输入非整型十进制数字
switch (a)
{
case 1:
game();
menu();
break;
case 0:
return 0;
default: printf("输入错误");
}
} while (a);
}
threechess.h
第二步 编写游戏功能的头文件
#pragma once
#define ROW 3
#define COL 3
void initboard(char arr[ROW][COL], int row, int col);//初始化棋盘
//打印棋盘
void display(char arr[ROW][COL], int row, int col);
//人走棋
void playermove(char arr[ROW][COL], int row, int col);
//机器走
void automove(char arr[ROW][COL], int row, int col);
//判断输赢
int JUDGE(char arr[ROW][COL], int row, int col);
//平局情况
int FULL(char arr[ROW][COL], int row, int col);
threechess.c
第三步在该源文件中定义功能
#include "threechess.h"
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
void initboard(char arr[ROW][COL], int row, int col)//此处第一个参数是指产生二维指针,不能够省略第一个下标符第二个下标符和值
{
int i = 0;
int j = 0;
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
arr[i][j] = ' '; //将内容初始化
}
}
}
void display(char arr[ROW][COL], int row, int col)//显示棋盘
{
int i = 0;
int j = 0;
printf("-------------\n");
for (i = 0; i < row; i++)
{
printf("|");
for (j = 0; j < col; j++)
{
printf(" %-2c|", arr[i][j]);
}
if (row - 2 == i)
{
(printf(" ***帮帮乌干达得可怜儿童!***")); // label 2.VIM version
}
printf("\n-------------\n");// 目的在于每行打印完了以后再下面加上栅;
}
}
void playermove(char arr[ROW][COL], int row, int col) //玩家移动
{
while (1)
{
int x = 0, y = 0;
assert(scanf("%d%d", &x, &y));//此处强调,如果用用户输入的值非十进制整型,比如%……&*&*!@#asdvc字符型,那么scanf函数将不进行匹配,返回匹配成功的项目数,用assert断言函数来进行判断
x--;//因为用户输入得值位数组下表加一所以在这里--
y--;
if ((x >= 0 && x < row) && (y >= 0 && y < col))//防止越界
{
if (' ' == arr[x][y])
{
arr[x][y] = '*';
break;
}
else
{
printf("\n此位置已放置\n");
}
}
else
{
printf("\n你飘了\n"); //没放好就是飘了
}
}
}
void automove(char arr[ROW][COL], int row, int col)//电脑移动
{
srand((unsigned)time(NULL)); //设置随机起点
while (1)
{
int x = rand() % 3; //使随机值在0-2
int y = rand() % 3;
if (' ' == arr[x][y]) //防止重叠
{
arr[x][y] = 'X';
break;
}
}
}
int JUDGE(char arr[ROW][COL], int row, int col) //判断
{
int i = 0;
for (i = 0; i < ROW; i++)//判断列
{
if (arr[i][COL - 1] == arr[i][COL - 2] && arr[i][COL - 2] == arr[i][COL - 3]) //此处当下标时 数值要-1 很关键!
{
if (arr[i][COL - 1] != ' ')
{
return arr[i][COL - 1];
}
}
}
for (i = 0; i < COL; i++) //判断行
{
if (arr[ROW - 1][i] == arr[ROW - 2][i] && arr[ROW - 2][i] == arr[ROW - 3][i])
{
if (arr[ROW - 1][i] != ' ')
{
return arr[ROW - 1][i];
}
}
}
if (arr[0][0] == arr[1][1] && arr[1][1] == arr[2][2]) //判断斜行
{
if (arr[0][0] != ' ')
{
return arr[0][0]; //返回复合条件的字符
}
}
if (arr[0][2] == arr[1][1] && arr[1][1] == arr[2][0])//判断对称斜行
{
if (arr[0][2] != ' ')
{
return arr[0][2]; //返回复合条件的字符
}
}
if (FULL(arr, row, col) == 0) //在judge中引用FULL函数进行平局判断
{
return 'd';//返回复合条件的字符
}
return 0; //没有返回0
}
int FULL(char arr[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 (' ' == arr[i][j])
{
return 1; //供judge判断
}
}
}
return 0;
}
第四步,game()功能实现
void game()
{
char arr[ROW][COL] = { 0 };
initboard(arr, ROW, COL);
display(arr, ROW, COL);
while (1)
{
playermove(arr, ROW, COL); //玩家操作
display(arr, ROW, COL);//将结果显示
if (JUDGE(arr, ROW, COL) != 0)//判断是否产生结果
{
break;
}
automove(arr, ROW, COL); //电脑操作
display(arr, ROW, COL);//显示结果
if (JUDGE(arr, ROW, COL) != 0)//判断
{
break;
}
}
if (JUDGE(arr, ROW, COL) =='d' )//结束后检测是否复合平局判断
{
printf("你勉强合格");//输出平局结果
}
else if (JUDGE(arr, ROW, COL) == 'X')//电脑胜出结果判断
{
printf("出门左转上336\n");
}
else if (JUDGE(arr, ROW, COL) == '*')//玩家结果判断
{
printf("THAT'S VERY KIND OF YOU!\n");
}
return 0;}
输出结果
1.界面
1.电脑赢
2.玩家赢
**对于label 1与2
1.来字linux系统经典字体测试
2.来自vim的欢迎语
显得更有意义。
**关于scanf的返回值,scanf返回的是正确入读的项目数,即(%d%d%d,&a,&b)它的返回值也是3,但是如果第一个项目未提取成功,那么即使后面是正确的类型,返回值也是0