/********************************************************************
C-4.29-1:
实现五子棋游戏
操作说明:用方向键或者"w","s","a","d"控制棋子放置位置,
使用空格键放置棋子,使用“ESC”键退出游戏
     测试环境:Redhat5.5
********************************************************************/ #include <stdio.h>
#include <string.h>
#include <stdlib.h> #define ROW 30
#define COL 36
#define MOVECOLOR 36
#define MOVECHAR '*' //初始化五子棋表格
void initbox(char p[][COL])
{
int i = 0, j = 0; for (i = 0; i < ROW; i++)
{
for (j = 0; j < COL; j++)
{
p[i][j] = '+';
}
}
} //打印显示五子棋表格
void show(char p[][COL])
{
int i = 0, j = 0; for (i = 0; i < ROW; i++)
{
for (j = 0; j < COL; j++)
{
printf("%c ", p[i][j]);
}
putchar(10);
}
} //将当前光标定位于指定的(x, y)处
void gotoxy(int x, int y)
{
printf("\033[%d;%dH", x, y);
} //显示光标所在位置的坐标值(x, y)
void showxy(int x, int y)
{
int i = 0;
printf("\033[s");
gotoxy(ROW+1, COL-6);
for (i = 0; i < 14; i++)
{
printf(" ");
}
//printf("\033[K\033[10;10m");
printf("\033[14D");
printf("x = %d y = %d\n", x, y); printf("\033[u");
} //移动光标到要下棋点
void move(char rect[][COL], char *buf, int *x, int *y, int player)
{
char ch = 0; if (0 == player % 2)
{
ch = '@';
}
else
{
ch = '#';
} //方向键控制区按键识别,并处理
if (buf[0] == 27 && buf[1] == 91)
{
switch (buf[2])
{
case 65:
if (*x > 1 && *x <= ROW) //上移处理
{
if (rect[*x-1][*y-1] == '+') //下棋点位置在移动时要判断该位置是否为空,为空则将空的颜色恢复黑色
printf("\033[10;10m+\033[D\033[0m");
printf("\033[A"); //上移
if (rect[*x-2][*y-1] == '+')
printf("\033[%d;10m%c\033[D\033[0m", MOVECOLOR, MOVECHAR); //将下棋点位置标明为特殊字符,以便于识别
*x -= 1;
}
break;
case 66:
if (*x >= 1 && *x < ROW) //下移处理
{
if (rect[*x-1][*y-1] == '+')
printf("\033[10;10m+\033[D\033[0m");
printf("\033[B");
if (rect[*x][*y-1] == '+')
printf("\033[%d;10m%c\033[D\033[0m", MOVECOLOR, MOVECHAR);
*x += 1;
}
break;
case 67:
if (*y >= 1 && *y < COL) //右移处理
{
if (rect[*x-1][*y-1] == '+')
printf("\033[10;10m+\033[D\033[0m");
printf("\033[2C");
if (rect[*x-1][*y] == '+')
printf("\033[%d;10m%c\033[D\033[0m", MOVECOLOR, MOVECHAR);
*y += 1;
}
break;
case 68:
if (*y > 1 && *y <= COL) //左移处理
{
if (rect[*x-1][*y-1] == '+')
printf("\033[10;10m+\033[D\033[0m");
printf("\033[2D");
if (rect[*x-1][*y-2] == '+')
printf("\033[%d;10m%c\033[D\033[0m", MOVECOLOR, MOVECHAR);
*y -= 1;
}
break;
default:
break;
}
} //左侧控制键"w","s","a","d"识别,并处理
if (0 == buf[1])
{
switch (buf[0])
{
case 119:
if (*x > 1 && *x <= ROW) //上移处理
{
if (rect[*x-1][*y-1] == '+') //下棋点位置在移动时要判断该位置是否为空,为空则将空的颜色恢复
printf("\033[10;10m+\033[D\033[0m");
printf("\033[A"); //上移
if (rect[*x-2][*y-1] == '+')
printf("\033[%d;10m%c\033[D\033[0m", MOVECOLOR, MOVECHAR); //将下棋点位置标明为特殊字符,以便于识别
*x -= 1;
}
break;
case 115:
if (*x >= 1 && *x < ROW) //下移处理
{
if (rect[*x-1][*y-1] == '+')
printf("\033[10;10m+\033[D\033[0m");
printf("\033[B");
if (rect[*x][*y-1] == '+')
printf("\033[%d;10m%c\033[D\033[0m", MOVECOLOR, MOVECHAR);
*x += 1;
}
break;
case 100:
if (*y >= 1 && *y < COL) //右移处理
{
if (rect[*x-1][*y-1] == '+')
printf("\033[10;10m+\033[D\033[0m");
printf("\033[2C");
if (rect[*x-1][*y] == '+')
printf("\033[%d;10m%c\033[D\033[0m", MOVECOLOR, MOVECHAR);
*y += 1;
}
break;
case 97:
if (*y > 1 && *y <= COL) //左移处理
{
if (rect[*x-1][*y-1] == '+')
printf("\033[10;10m+\033[D\033[0m");
printf("\033[2D");
if (rect[*x-1][*y-2] == '+')
printf("\033[%d;10m%c\033[D\033[0m", MOVECOLOR, MOVECHAR);
*y -= 1;
}
break;
default:
break;
}
}
showxy(*x, *y);
} void playerchk(int *player)
{
if (0 == *player % 2)
{
printf("\033[s");
gotoxy(ROW+1, 0);
printf("\033[K");
gotoxy(ROW+1, 2);
printf("\033[10;10mPlayerA\033[K\033[0m");
printf("\033[u");
}
else if (1 == *player % 2)
{
printf("\033[s");
gotoxy(ROW+1, 0);
printf("\033[K");
gotoxy(ROW+1, 32);
printf("\033[10;10mPlayerB\033[K\033[0m");
printf("\033[u");
}
} //检查是否有五个连续并且一样的字符,有则游戏结束
int resultchk(char rect[][COL])
{
int i = 0, j = 0, k = 0;
int count = 0;
char cha = '@';
char chb = '#';
char ch = 0; //检查各行是否有五个连续字符
for (i = 0; i < ROW; i++)
{
for (j = 0; j < COL-4; j++)
{
if ((rect[i][j] != '+') && (rect[i][j] == rect[i][j+1]) && (rect[i][j] == rect[i][j+2]) && (rect[i][j] == rect[i][j+3]) && (rect[i][j] == rect[i][j+4]))
{
if (cha == rect[i][j])
{
ch = cha;
gotoxy (ROW+2, COL-11);
printf("Game over! PlayerA win!\n");
}
else if (chb == rect[i][j])
{
ch = chb;
gotoxy (ROW+2, COL-11);
printf("Game over! PlayerB win!\n");
}
for (k = 0; k < 5; k++)
{
gotoxy(i+1, (j+k+1) * 2-1);
printf("\033[10;43m%c\033[0m", ch);
}
return 1;
}
}
}
//检查各列是否有五个连续字符
for (j = 0; j < ROW; j++)
{
for (i = 0; i < COL-4; i++)
{
if ((rect[i][j] != '+') && (rect[i][j] == rect[i+1][j]) && (rect[i][j] == rect[i+2][j]) && (rect[i][j] == rect[i+3][j]) && (rect[i][j] == rect[i+4][j]))
{
if (cha == rect[i][j])
{
ch = cha;
gotoxy (ROW+2, COL-11);
printf("Game over! PlayerA win!\n");
}
else if (chb == rect[i][j])
{
ch = chb;
gotoxy (ROW+2, COL-11);
printf("Game over! PlayerB win!\n");
}
for (k = 0; k < 5; k++)
{
gotoxy(i+k+1, (j+1) * 2-1);
printf("\033[10;43m%c\033[0m", ch);
}
return 1;
}
}
}
//检查左上-右下斜线上是否有五个连续字符相同
for (i = 0; i < ROW-4; i++)
{
for (j = 0; j < COL-4; j++)
{
if ((rect[i][j] != '+') && (rect[i][j] == rect[i+1][j+1]) && (rect[i][j] == rect[i+2][j+2]) && (rect[i][j] == rect[i+3][j+3]) && (rect[i][j] == rect[i+4][j+4]))
{
if (cha == rect[i][j])
{
ch = cha;
gotoxy (ROW+2, COL-11);
printf("Game over! PlayerA win!\n");
}
else if ('#' == rect[i][j])
{
ch = chb;
gotoxy (ROW+2, COL-11);
printf("Game over! PlayerB win!\n");
}
for (k = 0; k < 5; k++)
{
gotoxy(i+k+1, (j+k+1) * 2-1);
printf("\033[10;43m%c\033[0m", ch);
}
return 1;
}
}
}
//检查左下-右上斜线上是否有五个连续字符相同
for (i = 0; i < ROW-4; i++)
{
for (j = 4; j < COL; j++)
{
if ((rect[i][j] != '+') && (rect[i][j] == rect[i+1][j-1]) && (rect[i][j] == rect[i+2][j-2]) && (rect[i][j] == rect[i+3][j-3]) && (rect[i][j] == rect[i+4][j-4]))
{
if (cha == rect[i][j])
{
ch = cha;
gotoxy (ROW+2, COL-11);
printf("Game over! PlayerA win!\n");
}
else if (ch == rect[i][j])
{
ch = chb;
gotoxy (ROW+2, COL-11);
printf("Game over! PlayerB win!\n");
}
for (k = 0; k < 5; k++)
{
gotoxy(i+k+1, (j-k+1) * 2-1);
printf("\033[10;43m%c\033[0m", ch);
}
return 1;
}
}
}
} int main(void)
{
int i = 0, j = 0;
char rect[ROW][COL] = { 0 };
int ret = 0;
int x = ROW / 2, y = COL / 2;
int player = 0; system("clear");
system("stty -echo");
system("stty -icanon"); initbox(rect);
show(rect);
printf("\033[s");
gotoxy(ROW+1, 2);
printf("\033[10;10mPlayerA(@)\033[K\033[0m");
printf("\033[u");
gotoxy(x, y * 2 - 1);
showxy(x, y);
printf("\033[?25l");
if (rect[x-1][y-1] == '+')
{
printf("\033[%d;10m%c\033[D\033[0m", MOVECOLOR, MOVECHAR);
}
fflush(NULL); while (1)
{
int i = 0;
char buf[10] = { 0 };
ret = read(0, buf, 10);
move(rect, buf, &x, &y, player);
//if (buf[0] == 119)
//for (i = 0; i < ret; i++)
//{
// printf("buf[%d] = %d\n", i, buf[i]);
//} if (buf[0] == 32 && buf[1] == 0) //按下空格键,在当前位置放下棋子
{
if ((0 == player % 2) && (rect[x-1][y-1] == '+')) //玩家一回合内,按下空格,放置'@'
{
rect[x-1][y-1] = '@';
printf("\033[31;10m@\033[D\033[0m");
printf("\033[s");
gotoxy(ROW+1, 2);
printf("\033[K");
printf("\033[u");
showxy(x, y);
printf("\033[s");
gotoxy(ROW+1, COL * 2 - 10);
printf("\033[K");
printf("\033[10;10mPlayerB(#)\033[K\033[0m");
printf("\033[u");
player++;
}
else if ((1 == player % 2) && (rect[x-1][y-1] == '+')) //玩家二回合内,按下空格,放置'#'
{
rect[x-1][y-1] = '#';
printf("\033[32;10m#\033[D\033[0m");
printf("\033[s");
gotoxy(ROW+1, 2);
printf("\033[K");
printf("\033[10;10mPlayerA(@)\033[K\033[0m");
printf("\033[u");
showxy(x, y);
player++;
}
} if (buf[0] == 27 && buf[1] == 0) //按下ESC键退出游戏
{
if ('+' == rect[x-1][y-1])
printf("\033[10;10m+");
gotoxy(ROW+2, 0);
//show(rect);
break;
}
if (resultchk(rect) == 1)
{
break;
} fflush(NULL);
} gotoxy(ROW+3, 0);
printf("\033[?25h");
system("stty echo");
system("stty icanon"); return 0;
}

  

C语言实现五子棋简单功能的更多相关文章

  1. R语言:用简单的文本处理方法优化我们的读书体验

    博客总目录:http://www.cnblogs.com/weibaar/p/4507801.html 前言 延续之前的用R语言读琅琊榜小说,继续讲一下利用R语言做一些简单的文本处理.分词的事情.其实 ...

  2. Web应用开发工具及语言需要具备的功能探索

    1 前言 最近一个多月在做Web项目,用到的技术有(也不算泄漏公司机密吧): 后台:Struts 2(with JSP/FreeMarker).Spring.Hibernate.MySQL.Web S ...

  3. 用C语言编写一个简单的词法分析程序

    问题描述: 用C或C++语言编写一个简单的词法分析程序,扫描C语言小子集的源程序,根据给定的词法规则,识别单词,填写相应的表.如果产生词法错误,则显示错误信息.位置,并试图从错误中恢复.简单的恢复方法 ...

  4. 踢爆IT劣书出版黑幕——由清华大学出版社之《C语言入门很简单》想到的(1)

    1.前言与作者 首先声明,我是由于非常偶然的机会获得<C语言入门很简单>这本书的,绝对不是买的.买这种书实在丢不起那人. 去年这书刚出版时,在CU论坛举行试读推广,我当时随口说了几句(没说 ...

  5. 留念 C语言第一课简单的计算器制作

    留念 C语言第一课简单的计算器制作 学C语言这么久了.  /* 留念 C语言第一课简单的计算器制作 */   #include<stdio.h>  #include<stdlib.h ...

  6. 【 VS 插件开发 】三、Vs插件简单功能的实现

    [ VS 插件开发 ]三.Vs插件简单功能的实现

  7. C语言 实现逆置功能

    C语言 实现逆置功能 //凯鲁嘎吉 - 博客园 http://www.cnblogs.com/kailugaji/ 1. 字符串的逆置 方法1:利用数组 #include<stdio.h> ...

  8. 用Go语言实现一个简单的聊天机器人

    一.介绍 目的:使用Go语言写一个简单的聊天机器人,复习整合Go语言的语法和基础知识. 软件环境:Go1.9,Goland 2018.1.5. 二.回顾 Go语言基本构成要素:标识符.关键字.字面量. ...

  9. Fastjson是一个Java语言编写的高性能功能完善的JSON库。

    简介 Fastjson是一个Java语言编写的高性能功能完善的JSON库. 高性能 fastjson采用独创的算法,将parse的速度提升到极致,超过所有json库,包括曾经号称最快的jackson. ...

随机推荐

  1. Java 抽象类与接口总结

    一.为什么要使用抽象类?有什么好处? 抽象类是通用接口.不同的子类可以用不同的方法表示此接口.通用接口建立起一种基本形式,以此表示所有子类的共同部分. 必须覆写父类abstract抽象的方法  含有抽 ...

  2. ueditor编辑器图片自定义存放目录及路径修改

    百度编辑器ueditor功能强大,很多人士以应用项目开发中,但是里面有一个公众的问题就是上传图片存放目录太深,默认是ueditor/php/upload下,前不久测试后图片存放目录可以改变,但是路径会 ...

  3. 基于特定领域国土GIS应用框架设计及应用

              基于特定领域国土GIS应用框架 设计及应用              何仕国 2012年8月16日   摘要: 本文首先讲述了什么是框架和特定领域框架,以及与国土GIS 这个特定领 ...

  4. GitHub具体教程

    GitHub具体教程 Table of Contents 1 Git具体教程 1.1 Git简单介绍 1.1.1 Git是何方神圣? 1.1.2 重要的术语 1.1.3 索引 1.2 Git安装 1. ...

  5. oracle9

    约束 维护数据的完整性 数据的完整性用于确保数据库数据遵从一定的商业和逻辑规则(比如年纪不能为-,性别不能为非男女),在oracle中,数据完整性可以使用约束.触发器.应用程序(过程.函数)三种方法来 ...

  6. java反射性能

    项目中用到了java的反射,可以大大减少代码量.但是反射的性能却不容乐观,做了个简单的测试,如下. public void noreflect() { Person p = new Person(); ...

  7. Day04 - Python 迭代器、装饰器、软件开发规范

    1. 列表生成式 实现对列表中每个数值都加一 第一种,使用for循环,取列表中的值,值加一后,添加到一空列表中,并将新列表赋值给原列表 >>> a = [0, 1, 2, 3, 4, ...

  8. git 删除配置的远程地址

    删除(origin 名称需根据你本地查询出来的想删除的名字, 查询命令为 git remote -v) git remote rm origin 添加(origin 名称可根据需要添加) git re ...

  9. python下操作ftp上传

    生产情况:tomcat下业务log备份,目录分多级,然后对应目录格式放到ftp上:所以,结构上 我就是一级一级目录进行判断(因为我没有找到在ftp一次判断其子目录是否存在),还有一个low点就是我没有 ...

  10. nodejs 中koa框架下的微信公众号开发初始篇

    最近在搞微信公众号开发,后端采用的是nodejs下的koa框架,初识后端的菜鸟,自己搞难度太大了,网上找了很多文章,采用的中间件大都是express框架下的,不过好在爬了许多坑之后总算看见点曙光了,遂 ...