C语言实现五子棋简单功能
/********************************************************************
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语言实现五子棋简单功能的更多相关文章
- R语言:用简单的文本处理方法优化我们的读书体验
博客总目录:http://www.cnblogs.com/weibaar/p/4507801.html 前言 延续之前的用R语言读琅琊榜小说,继续讲一下利用R语言做一些简单的文本处理.分词的事情.其实 ...
- Web应用开发工具及语言需要具备的功能探索
1 前言 最近一个多月在做Web项目,用到的技术有(也不算泄漏公司机密吧): 后台:Struts 2(with JSP/FreeMarker).Spring.Hibernate.MySQL.Web S ...
- 用C语言编写一个简单的词法分析程序
问题描述: 用C或C++语言编写一个简单的词法分析程序,扫描C语言小子集的源程序,根据给定的词法规则,识别单词,填写相应的表.如果产生词法错误,则显示错误信息.位置,并试图从错误中恢复.简单的恢复方法 ...
- 踢爆IT劣书出版黑幕——由清华大学出版社之《C语言入门很简单》想到的(1)
1.前言与作者 首先声明,我是由于非常偶然的机会获得<C语言入门很简单>这本书的,绝对不是买的.买这种书实在丢不起那人. 去年这书刚出版时,在CU论坛举行试读推广,我当时随口说了几句(没说 ...
- 留念 C语言第一课简单的计算器制作
留念 C语言第一课简单的计算器制作 学C语言这么久了. /* 留念 C语言第一课简单的计算器制作 */ #include<stdio.h> #include<stdlib.h ...
- 【 VS 插件开发 】三、Vs插件简单功能的实现
[ VS 插件开发 ]三.Vs插件简单功能的实现
- C语言 实现逆置功能
C语言 实现逆置功能 //凯鲁嘎吉 - 博客园 http://www.cnblogs.com/kailugaji/ 1. 字符串的逆置 方法1:利用数组 #include<stdio.h> ...
- 用Go语言实现一个简单的聊天机器人
一.介绍 目的:使用Go语言写一个简单的聊天机器人,复习整合Go语言的语法和基础知识. 软件环境:Go1.9,Goland 2018.1.5. 二.回顾 Go语言基本构成要素:标识符.关键字.字面量. ...
- Fastjson是一个Java语言编写的高性能功能完善的JSON库。
简介 Fastjson是一个Java语言编写的高性能功能完善的JSON库. 高性能 fastjson采用独创的算法,将parse的速度提升到极致,超过所有json库,包括曾经号称最快的jackson. ...
随机推荐
- 常用对象API、附加:集合补充
基本数据类型对象包装类: 为了方便操作基本数据类型值,将其封装成了对象,在对象中定义了属性和行为丰富了该数据的操作. 用于描述该对象的类就称为基本数据类型对象包装类. byte——Byte short ...
- Quartz定时任务学习(四)调度器
org.quartz.Scheduler 类层次 作为一个 Quartz 用户,你要与实现了 org.quartz.Scheduler 接口的类交互.在你调用它的任何 API 之前,你需要知道如何创建 ...
- 设计模式24---设计模式之职责链模式(Chain of Responsibility)(行为型)
1.职责链模式讲解 1.1职责链定义 使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系.将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止. 1.2职责链模式 ...
- foreach -begin -process -end
gc d:\vm.txt|foreach -begin {write-host "It's beginning."} -process {$_ +"aa"} ...
- EasyUI-页面布局
通过使用 jQuery EasyUI 可以很容易地添加 Tabs.您只需要调用 'add' 方法即可. 在本教程中,我们将使用 iframe 动态地添加显示在一个页面上的 Tabs. 当点击添加按钮, ...
- Android开发_Android数据的四种存储方式
Android系统一共提供了四种数据存储方式.分别是:SharePreference.SQLite.Content Provider和File.由于Android系统中,数据基本都是私有的的,都是存放 ...
- android 76 使用get post方式提交数据
get方式: package com.itheima.getmethod; import java.io.InputStream; import java.net.HttpURLConnection; ...
- go 初使用
hello.go package main import "fmt" func main(){ fmt.Println("hello world") 直接运行 ...
- NDK-r7以上版本部署方法
一.关于NDK: NDK全称:Native Development Kit. 1.NDK是一系列工具的集合. NDK提供了一系列的工具,帮助开发者快速开发C(或C++)的动态库,并能自动将so和jav ...
- angularjs 更新局部作用域
前几天项目需要,做了一个背景遮罩的弹出框,html采用js动态添加进去的,结果发现angularjs绑定在这里面不起作用,搜索下解决了,记录下: var smallApplyParent = docu ...