五子棋编程
#include "graphics.h"#include <locale.h>
<<graphics.c>>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
typedef unsigned int uint;
WINDOW * g_win=NULL;
GRAPHICS_COLOR g_fore_color=GCWhite;
GRAPHICS_COLOR g_back_color=GCCyan;
int g_style=A_BOLD;
#define CURRENT_ATTRIBUTE C_ATTR(g_style, g_fore_color, g_back_color)
int readkey()
{
int n, flags;
int ch=getc(stdin);
if(ch==27)
{
flags=fcntl(STDIN_FILENO, F_GETFL, 0);//获得文件状态标志
fcntl(STDIN_FILENO, F_SETFL, flags|O_NONBLOCK);//写入新加入属性
ch=getc(stdin);
if(ch==91)
{
ch=getc(stdin);
switch(ch)
{
case 'D':
ch=KEYLEFT;
break;
case 'C':
ch=KEYRIGHT;
break;
case 'B':
ch=KEYDOWN;
break;
case 'A':
ch=KEYUP;
break;
default:
ch=0;
}
}
else
{
ch=27;
}
fcntl(STDIN_FILENO, F_SETFL, flags);
}
return ch;
}
GRAPHICS_COLOR get_fore_color()
{
return g_fore_color;
}
void set_fore_color(GRAPHICS_COLOR color)
{
g_fore_color=GCWhite;
}
void set_back_color(GRAPHICS_COLOR color)
{
g_back_color=GCCyan;
}
void update_attribute(void)
{
wattrset(g_win, CURRENT_ATTRIBUTE);
}
void clear_screen(int x, int y, int w, int h)
{
int i, j;
for(i=0; i<h; i++)
{
wmove(g_win, i+y, x);
for(j=0; j<w; j++)
{
waddch(g_win, ' ');//waddstr
}
}
wrefresh(g_win);
}
bool init_graphics(void)
{
setlocale(LC_ALL, "zh_CN.UTF-8");
g_win=initscr();//在当前终端开启curses模式,
//当前终端即为一个窗口,返回其句柄
if(g_win==NULL)
{
printf("call initscr() failed!\n");
return false;
}
cbreak();//键盘输入不缓存 对键盘的操作立即可读 不等待回车
noecho();//键盘输入不回显
curs_set(0);//设置光标不可见
if(has_colors())//终端是否支持彩色
{
int i,j,k;
start_color();//开启彩色模式
for(i=0, k=0; i<GCCount; i++)
{
for(j=0; j<GCCount; j++)
{
init_pair(++k, i, j);//把前景色和背景色组合起来 产生一串编号 k
}
}
}
set_back_color(GCCyan);
update_attribute();//使改变生效
clear_screen(0, 0, COLS, LINES);//当前终端的大小 以字符为单位的
wrefresh(g_win);//刷新当前窗口
return true;
}
void exit_graphics(void)
{
endwin();//在当前终端上退出curses模式
}
void setduihuakuang(char *str,char *str1,char *str2)
{
g_back_color=GCBlack;
wattrset(g_win, CURRENT_ATTRIBUTE);
clear_screen(34,9,21,5);
g_back_color=GCMagenta;
wattrset(g_win, CURRENT_ATTRIBUTE);
clear_screen(30,10,20,5);
g_fore_color=GCWhite;
g_back_color=GCCyan;
mvaddstr(10,36,str);
mvaddstr(12,32,str1);
mvaddstr(12,40,str2);
wrefresh(g_win);
}
void drawchessboard( ) //画棋盘
{
int i,j;
for(i=0;i<21;i++)
{
wmove(g_win,i,0);
if(i==0)
{
for(j=0;j<15;j++)
{
if(j==0)
{
waddstr(g_win,TLC_FRAME);
}
waddstr(g_win,"\b");
waddstr(g_win,HLINE);
waddstr(g_win,HLINE);
waddstr(g_win,TMC_FRAME);
wrefresh(g_win);
}
}
if(i%2!=0)
{
for(j=0;j<80;j=j+5)
{
wmove(g_win,i,j);
waddstr(g_win,VLINE);
wrefresh(g_win);
}
}
if(i%2==0&&i!=0)
{
for(j=0;j<15;j++)
{
if(j==0)
{
waddstr(g_win,MLC_FRAME);
}
waddstr(g_win,"\b");
waddstr(g_win,HLINE);
waddstr(g_win,HLINE);
waddstr(g_win,MMC_FRAME);
wrefresh(g_win);
}
}
if(i==20)
{
wmove(g_win,i,0);
for(j=0;j<15;j++)
{
if(j==0)
{
waddstr(g_win,BLC_FRAME);
}
waddstr(g_win,"\b");
waddstr(g_win,HLINE);
waddstr(g_win,HLINE);
waddstr(g_win,BMC_FRAME);
wrefresh(g_win);
}
}
}
}
int selcetgameways( ) //选择模式
{
setduihuakuang("chose","cVSp","pVSp");
int flag;
int ch;
while(1)
{
ch=readkey( );
if(ch==KEYLEFT)
{
attron(A_REVERSE);
mvaddstr(12,32,"cVSp");
attroff(A_REVERSE);
mvaddstr(12,40,"pVSp");
wrefresh(g_win);
flag=0;
}
else if(ch==KEYRIGHT)
{
mvaddstr(12,32,"cVSp");
attron(A_REVERSE);
mvaddstr(12,40,"pVSp");
attroff(A_REVERSE);
wrefresh(g_win);
flag=1;
}
else
{
break;
}
}
return flag;
}
int selectchesscolor( ) //选择棋子颜色
{
setduihuakuang("chose","white","black");
int flag;
int ch;
while(1)
{
ch=readkey( );
if(ch==KEYLEFT)
{
attron(A_REVERSE);
mvaddstr(12,32,"white");
attroff(A_REVERSE);
mvaddstr(12,40,"black");
wrefresh(g_win);
flag=0;
}
else if(ch==KEYRIGHT)
{
mvaddstr(12,32,"white");
attron(A_REVERSE);
mvaddstr(12,40,"black");
attroff(A_REVERSE);
wrefresh(g_win);
flag=1;
}
else
{
break;
}
}
return flag;
}
void huifu( ) //恢复棋盘背景
{
g_fore_color=GCWhite;
g_back_color=GCCyan;
wattrset(g_win, CURRENT_ATTRIBUTE);
clear_screen(0,0,COLS,LINES);
drawchessboard( );
}
void fallwhitechess(int i,int j) //落白棋
{
wmove(g_win,i,j);
g_fore_color=GCWhite;
g_back_color=GCCyan;
wattrset(g_win, CURRENT_ATTRIBUTE);
waddstr(g_win,CHESS);
wrefresh(g_win);
}
void fallblackchess(int x,int y) //落黑棋
{
wmove(g_win,x,y);
g_fore_color=GCBlack;
g_back_color=GCCyan;
wattrset(g_win, CURRENT_ATTRIBUTE);
waddstr(g_win,CHESS);
wrefresh(g_win);
}
int judgewin(int a[25][80],int x,int y,int k) //判赢
{
int p;int q;
int count;
for(count=0,p=x,q=y-5;q>=0;q=q-5)
{
if(a[p][q]==k)
{
count++;
}
else
{
break;
}
}
for(p=x,q=y+5;q<=75;q=q+5)
{
if(a[p][q]==k)
{
count++;
}
else
{
break;
}
}
if(count>=4&&a[x][y]==k)
return 1;
for(count=0,p=x-2,q=y-5;p>=0,q>=0;p=p-2,q=q-5)
{
if(a[p][q]==k)
{
count++;
}
else
{
break;
}
}
for(p=x+2,q=y+5;p<=20,q<=75;p=p+2,q=q+5)
{
if(a[p][q]==k)
{
count++;
}
else
{
break;
}
}
if(count>=4&&a[x][y]==k)
return 1;
for(count=0,p=x-2,q=y;p>=0;p=p-2)
{
if(a[p][q]==k)
{
count++;
}
else
{
break;
}
}
for(p=x+2,q=y;p<=20;p=p+2)
{
if(a[p][q]==k)
{
count++;
}
else
{
break;
}
}
if(count>=4&&a[x][y]==k)
return 1;
for(count=0,p=x+2,q=y-5;p<=20,q>=0;p=p+2,q=q-5)
{
if(a[p][q]==k)
{
count++;
}
else
{
break;
}
}
for(p=x-2,q=y+5;p>=0,q<=75;p=p-2,q=q+5)
{
if(a[p][q]==k)
{
count++;
}
else
{
break;
}
}
if(count>=4&&a[x][y]==k)
return 1;
return 0;
}
int again( ) //选择是否重新开始
{
curs_set(0);
int m=readkey( );
if(m==KEYUP)
{
setduihuakuang("want again?","Yes","No");
}
int ch;
int flag;
while(1)
{
ch=readkey( );
if(ch==KEYLEFT)
{
attron(A_REVERSE);
mvaddstr(12,32,"Yes");
attroff(A_REVERSE);
mvaddstr(12,40,"No");
wrefresh(g_win);
flag=1;
}
else if(ch==KEYRIGHT)
{
mvaddstr(12,32,"Yes");
attron(A_REVERSE);
mvaddstr(12,40,"No");
attroff(A_REVERSE);
wrefresh(g_win);
flag=0;
}
else
{
break;
}
}
curs_set(1);
return flag;
}
void func( ) //调用重新开始
{
void gameway( );
while(1)
{
int flag=again( );
if(flag==1)
{
gameway( );
}
else
{
exit_graphics( );
}
}
}
void pVSp( ) //人与人对战
{
int a[25][80]={0};
int flag1=1;
int x=StartX;
int y=StartY;
int flag = selectchesscolor( );
huifu( );
drawchessboard( );
wmove(g_win,x,y);
wrefresh(g_win);
do
{
int ch;
ch=readkey( );
if(ch==KEYUP)
{
if(a[x-2][y]==0&&x!=0)
{
x=x-2;wmove(g_win,x,y);wrefresh(g_win);flag1=1;
}
else if(a[x-2][y]!=0&&x!=0)
{
x=x-2;wmove(g_win,x,y);wrefresh(g_win);
flag1=0;
}
else
{
flag1=0;
}
}
else if(ch==KEYDOWN)
{
if(a[x+2][y]==0&&x!=20)
{
x=x+2;wmove(g_win,x,y);wrefresh(g_win);flag1=1;
}
else if(a[x+2][y]!=0&&x!=20)
{
x=x+2;wmove(g_win,x,y);wrefresh(g_win);
flag1=0;
}
else
{
flag1=0;
}
}
else if(ch==KEYLEFT)
{
if(a[x][y-5]==0&&y!=0)
{
y=y-5;wmove(g_win,x,y);wrefresh(g_win);flag1=1;
}
else if(a[x][y-5]!=0&&y!=0)
{
y=y-5;wmove(g_win,x,y);wrefresh(g_win);
flag1=0;
}
else
{
flag1=0;
}
}
else if(ch==KEYRIGHT)
{
if(a[x][y+5]==0&&y!=75)
{
y=y+5;wmove(g_win,x,y);wrefresh(g_win);flag1=1;
}
else if(a[x][y+5]!=0&&y!=75)
{
y=y+5;wmove(g_win,x,y);wrefresh(g_win);
flag1=0;
}
else
{
flag1=0;
}
}
else
{
if(flag==1&&flag1==1)
{
fallblackchess(x,y);
a[x][y]=1;
flag=0;
if(1==judgewin(a,x,y,1))
{
setduihuakuang(" ","BlackWin"," ");
break;
}
wrefresh(g_win);
}
else if(flag==0&&flag1==1)
{
fallwhitechess(x,y);
a[x][y]=2;
flag=1;wrefresh(g_win);
if(1==judgewin(a,x,y,2))
{
setduihuakuang(" ","WhiteWin"," ");
break;
}
wrefresh(g_win);
}
}
}while(1);
func( );
}
int score1(int count,int flag1,int flag2) //每行列左斜右斜的分值
{
if(count>=5)// 成5
return 30000;
if(count==4 && flag1==1 && flag2==1) //活4
return 10000;
if(count==4 && ((flag1==1 && flag2==0) || (flag1==0 && flag2==1))) //死4
return 500;
if(count==3 && flag1==1 && flag2==1) //活3
return 200;
if(count==3 && ((flag1==1 && flag2==0) || (flag1==0 && flag2==1))) //死3
return 50;
if(count==2 && flag1==1 && flag2==1) //活2
return 5;
if(count==2 && ((flag1==1 && flag2==0) || (flag1==0 && flag2==1))) //死2
return 3;
return 0;
}
int chess_level(int c[4]) //赋分
{
if(c[0]==30000 || c[1]==30000 || c[2]==30000 || c[3]==30000) // 成5
return 30000;
if(c[0]+c[1]+c[2]+c[3]>=1000)//双死4 或 活4
return 10000;
if(c[0]+c[1]+c[2]+c[3]>=700) // 死4活3
return 8000;
if((c[0]+c[1]+c[2]+c[3]>=10000) && (c[0]!=500 && c[4]!=500 && c[2]!=500 && c[3]!=500) ) // 双活3
return 5000;
if(c[0]+c[1]+c[2]+c[3]>=250 && (c[0]!=500 && c[4]!=500 && c[2]!=500 && c[3]!=500) ) // 死3活3
return 1000;
if(c[0]==500 || c[1]==500 || c[2]==500 || c[3]==500 || c[0]==200 || c[1]==200 || c[2]==200 || c[3]==200) // 单活3或死4
return 200;
if((c[0]+c[1]+c[2]+c[3]>=20 && c[0]!=50 && c[1]!=50 && c[2]!=50 && c[3]!=50)|| (c[0]==50 || c[1]==50 || c[2]==50 || c[3]==50)) //双活2或死3
return 10;
if(c[0]==10 || c[1]==10 || c[2]==10 || c[3]==10) //单活2
return 5;
if(c[0]==5 || c[1]==5 || c[2]==5 || c[3]==5) //死2
return 3;
return 0;
}
void score(int x,int y,int a[25][80],int b[25][80],int k)
{
int x1,y1,count,flag1=0,flag2=0;
int c[4]={0};
//横向
for(flag2=0,count=1,x1=x,y1=y+5;y1>=0 && y1<=75 && a[x1][y1]==k;y1=y1+5)
{
count++;
}
if(y1<80 && a[x1][y1]==0)
flag2=1;
for(flag1=0,x1=x,y1=y-5;y1>=0 && y1<=75 && a[x1][y1]==k;y1=y1-5)
{
count++;
}
if(y1>=0 && a[x1][y1]==0)
flag1=1;
c[0]=score1(count,flag1,flag2);
//纵向
for(flag2=0,count=1,x1=x+2,y1=y;x1>=0 && x1<=20 && a[x1][y1]==k;x1=x1+2)
{
count++;
}
if(x1<=20 && a[x1][y1]==0)
flag2=1;
for(flag1=0,x1=x-2,y1=y;x1>=0 && x1<=20 && a[x1][y1]==k;x1=x1-2)
{
count++;
}
if(x1>=0 && a[x1][y1]==0)
flag1=1;
c[1]=score1(count,flag1,flag2);
//左斜
for(flag2=0,count=1,x1=x+2,y1=y+5;x1>=0 && x1<=20 && y1>=0 && y1<=75 && a[x1][y1]==k;x1=x1+2,y1=y1+5)
{
count++;
}
if(x1<=20 && y1<80 && a[x1][y1]==0)
flag2=1;
for(flag1=0,x1=x-2,y1=y-5;x1>=0 && x1<=20 && y1>=0 && y1<=75 && a[x1][y1]==k;x1=x1-2,y1=y1-5)
{
count++;
}
if(x1>=0 && y1>=0 && a[x1][y1]==0)
flag1=1;
c[2]=score1(count,flag1,flag2);
//右斜
for(flag2=0,count=1,x1=x-2,y1=y+5;x1>=0 && x1<=20 && y1>=0 && y1<=75 && a[x1][y1]==k;x1=x1-2,y1=y1+5)
{
count++;
}
if(x1>=0 && y1<=20 && a[x1][y1]==0)
flag2=1;
for(flag1=0,x1=x+2,y1=y-5;x1>=0 && x1<=20 && y1>=0 && y1<=75 && a[x1][y1]==k;x1=x1+2,y1=y1-5)
{
count++;
}
if(x1<=20 && y1>=0 && a[x1][y1]==0)
flag1=1;
c[3]=score1(count,flag1,flag2);
b[x][y]=chess_level(c);
}
void chess_score(int a[25][80],int b1[25][80],int b2[25][80])//棋盘各个空格的分值
{
int x,y;
for(x=0;x<=20;x=x+2)
{
for(y=0;y<=75;y=y+5)
{
if(a[x][y]==0)
{
score(x,y,a,b1,1);//黑子
score(x,y,a,b2,2);//白子
}
}
}
}
void fallchess(int a[25][80],int x,int y,int flag) //电脑落棋
{
if(flag==1)
{
wmove(g_win,x,y);
fallwhitechess(x,y);
a[x][y]=2;
wrefresh(g_win);
}
else
{
wmove(g_win,x,y);
fallblackchess(x,y);
a[x][y]=1;
wrefresh(g_win);
}
}
void mango(int a[25][80],int flag) //人机对战时人走棋
{
int flag1=1;
int x=StartX;int y=StartY;
do
{
int ch;
ch=readkey( );
if(ch==KEYUP)
{
if(a[x-2][y]==0&&x!=0)
{
x=x-2;wmove(g_win,x,y);wrefresh(g_win);flag1=1;
}
else if(a[x-2][y]!=0&&x!=0)
{
x=x-2;wmove(g_win,x,y);wrefresh(g_win);flag1=0;
}
else
{
flag1=0;
}
}
else if(ch==KEYDOWN)
{
if(a[x+2][y]==0&&x!=20)
{
x=x+2;wmove(g_win,x,y);wrefresh(g_win);flag1=1;
}
else if(a[x+2][y]!=0&&x!=20)
{
x=x+2;wmove(g_win,x,y);wrefresh(g_win);flag1=0;
}
else
{
flag1=0;
}
}
else if(ch==KEYLEFT)
{
if(a[x][y-5]==0&&y!=0)
{
y=y-5;wmove(g_win,x,y);wrefresh(g_win);flag1=1;
}
else if(a[x][y-5]!=0&&y!=0)
{
y=y-5;wmove(g_win,x,y);wrefresh(g_win);flag1=0;
}
else
{
flag1=0;
}
}
else if(ch==KEYRIGHT)
{
if(a[x][y+5]==0&&y!=75)
{
y=y+5;wmove(g_win,x,y);wrefresh(g_win);flag1=1;
}
else if(a[x][y+5]!=0&&y!=75)
{
y=y+5;wmove(g_win,x,y);wrefresh(g_win);flag1=0;
}
else
{
flag1=0;
}
}
else
{
if(flag==1&&flag1==1)
{
fallblackchess(x,y);
a[x][y]=1;
if(1==judgewin(a,x,y,1))
{
setduihuakuang(" ","BlackWin"," ");
func( );
}
return;
}
else if(flag==0&&flag1==1)
{
fallwhitechess(x,y);
a[x][y]=2;
wrefresh(g_win);
if(1==judgewin(a,x,y,2))
{
setduihuakuang(" ","WhiteWin"," ");
func( );
}
return;
}
}
}while(1);
}
void computergo(int a[25][80],int flag) //电脑走棋
{
int b1[25][80]={0};
int b2[25][80]={0};
chess_score(a,b1,b2);
int x,y;
int f=0;
int p1=0,q1=0;
int p2=0,q2=0;
int maxscore1=0;
for(x=0;x<=20;x=x+2)
{
for(y=0;y<=75;y=y+5)
{
if(b1[x][y]>maxscore1)
{
maxscore1=b1[x][y];
p1=x;q1=y;
}
}
}
wmove(g_win,p1,q1);
int i,j;
int maxscore2=b2[0][0];
for(i=0;i<=20;i=i+2)
{
for(j=0;j<=75;j=j+5)
{
wmove(g_win,i,j);
if(b2[i][j]>maxscore2)
{
maxscore2=b2[i][j];
p2=i;q2=j;
}
}
}
int m;
int n;
if(flag==1)
{
if(maxscore1==30000&&maxscore2==30000)
{
m=p2;n=q2;
}
else if(maxscore1>maxscore2||(maxscore1==maxscore2&&maxscore1!=30000&&maxscore2!=30000))
{
m=p1;n=q1;
}
else
{
m=p2;n=q2;
}
}
else
{
if(maxscore1==30000&&maxscore2==30000)
{
m=p1;n=q1;
}
else if(maxscore2>maxscore1||(maxscore1==maxscore2&&maxscore1!=30000&&maxscore2!=30000))
{
m=p2;n=q2;
}
else
{
m=p1;n=q1;
}
}
fallchess(a,m,n,flag);
while(1)
{
if(flag==0)
{
if(1==judgewin(a,m,n,1))
{
setduihuakuang(" ","BlackWin"," ");
func( );
again( );
}
return;
}
else
{
if(1==judgewin(a,m,n,2))
{
setduihuakuang(" ","WhiteWin"," ");
func( );
}
return;
}
}
}
void cVSp( ) //人机对战
{
int a[25][80]={0};
curs_set(1);
int x=StartX;
int y=StartY;
int flag=selectchesscolor( );//人先走
huifu( );
drawchessboard( );
wmove(g_win,x,y);
wrefresh(g_win);
do
{
mango(a,flag);
computergo(a,flag);
}while(1);
wrefresh(g_win);
}
void gameway( ) //选择对战模式
{
int flag=selcetgameways( );
if(flag==0)
{
curs_set(1);
cVSp( );
curs_set(0);
}
else
{
curs_set(1);
pVSp( );
curs_set(0);
}
}
<<main>>
#include "graphics.h"
#include <locale.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
int main( )
{
init_graphics( );
gameway( );
return 0;
}
<<graphics.h>>
#ifndef FPCHESS_GRAPHICS_HEADER
#define FPCHESS_GRAPHICS_HEADER
#include <ncurses/ncurses.h>
typedef enum{GCBlack, GCRed, GCGreen, GCYellow, GCBlue, GCMagenta, GCCyan, GCWhite, GCCount} GRAPHICS_COLOR;
typedef enum{LEFT, LEFTTOP, TOP, RIGHTTOP, RIGHT, RIGHTBOTTOM, BOTTOM, LEFTBOTTOM} DIRECTION;
#define C_ATTR(a, f, b) ((a)|COLOR_PAIR((f)*GCCount+(b)+1))
/* A_NORMAL Normal display (no highlight)
A_STANDOUT Best highlighting mode of the terminal.
A_UNDERLINE Underlining
A_REVERSE Reverse video
A_BLINK Blinking
A_DIM Half bright
A_BOLD Extra bright or bold
A_PROTECT Protected mode
A_INVIS Invisible or blank mode
A_ALTCHARSET Alternate character set
A_CHARTEXT Bit-mask to extract a character
*/
#define CHESS "● "
#define TLC_FRAME "┏ "
#define TMC_FRAME "┳ "
#define TRC_FRAME "┓ "
#define BLC_FRAME "┗ "
#define BMC_FRAME "┻ "
#define BRC_FRAME "┛ "
#define MLC_FRAME "┣ "
#define MMC_FRAME "╋ "
#define MRC_FRAME "┫ "
#define HLINE "━ "
#define VLINE "┃ "
#define KEYUP 0x30ff
#define KEYDOWN 0x31ff
#define KEYLEFT 0x32ff
#define KEYRIGHT 0x33ff
#define StartX 6
#define StartY 15
bool init_graphics(void);
void exit_graphics(void);
GRAPHICS_COLOR get_fore_color();
void set_fore_color(GRAPHICS_COLOR color);
void setduihuakuang1( );
void setduihuakuang2( );
void addwenzi( );
void drawchessboard( );
extern WINDOW * g_win;
void drawchessboard( );
#endif