1.[代码][C/C++]代码
/*
* reversi.cpp
* 转载请保留这段注释,注明原作者,以及出处,请尊重作者的劳动,谢谢!
* Created on: 2012-11-27
* Author: locusxt
* blog: http://my.oschina.net/u/1053833
*/
#include
#include
#include
#include
#include
using namespace std;
int t[8] = {0};
int huihe = 0;
int g = 0, h = 0;
int difficulty = 0;
int dx[8] = {0, 1, 1, 1, 0, -1, -1, -1};
int dy[8] = {-1, -1, 0, 1, 1, 1, 0, -1};
int player, ai;
int mover;
int boardcopy[13][13];
int board[13][13] = {0};
//以下为优先权数组
int priority[13][13] = {{0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 10000, 1, 18, 14, 14, 18, 1, 10000},
{0, 1, 1, 6, 7, 7, 6, 1, 1},
{0, 18, 6, 18, 12, 12, 18, 6, 18},
{0, 14, 13, 12, 11, 11, 12, 13, 14},
{0, 14, 13, 12, 11, 11, 12, 13, 14},
{0, 18, 6, 18, 12, 12, 18, 6, 18},
{0, 1, 1, 6, 7, 7, 6, 1, 1},
{0, 10000, 1, 18, 14, 14, 18, 1, 10000},
};
void save();//保存
void load();//载入
void printmap();//打印棋盘
int direction (int x, int y, int dir, char turn, int mode[][13]);//判断个方向能吃的棋子个数
int sum(int x, int y, int turn, int mode[][13]);//计数,放在(x,y)点可吃棋子总数
void choose();//选择先下还是后下,先下输入1,后下输入2,并且告知棋子颜色
int judgepass(int turn, int mode[][13] );//判断是否无棋可下,0代表不要pass,1则pass
void reverse(int x, int y, int turn,int mode[][13]);//翻转已经被吃掉的棋子
void input(int x, int y, int turn);//输入坐标或者指令
void tryin(int turn);//电脑ai模拟下棋
int calculate();//计算ai与player得分之差
void test (int step);//ai模拟下棋函数
float prio(int x, int y);//优先级函数
void aiinput();//ai输入
void mark(int turn);//标记可以下的位置
void remark( );//取消标记
void start();//游戏开始函数
void result();//输出游戏结果
void choosedifficulty();//选择难度
void tempsave();//临时保存
void choosemode();//选择模式
void regret();//悔棋
void outputhelp();//输出帮助文档
void giveup();//认输
int main ()
{
cout << "*******************************************" << endl;
cout << " 黑白棋 "<< endl;
cout << " Author:locusxt " << endl;
cout << " 2012.12" << endl << endl << endl;
board[4][4] = 2;
board[4][5] = 1;
board[5][4] = 1;
board[5][5] = 2;
outputhelp();
choosemode();
cout << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" << endl;
result();
cout << "Happy" << endl;
cout << " New" << endl;
cout << " Year!!!" << endl;
cout << "是否重新开始?(Y/N)" << endl;//一局游戏结束后询问是否继续玩
char letter;
cin >> letter;
if(letter == 'y')
{
system("CLS");
system("reversi.exe");
}
else exit(0);
system("pause");
}
void save()//保存功能
{
ofstream outfile("save.dat", ios::out);
if(!outfile)
{
cerr << "open error!" << endl;
exit(1);
}
else cout << "保存成功" << endl;
outfile << player << " " << ai << " " << difficulty << " " << huihe << endl;
for(int i = 1; i <= 8; i++)
for(int j = 1; j <= 8; j++)
outfile << board[i][j] << " ";
outfile.close();
}
void load()//读取功能
{
ifstream infile("save.dat", ios::in);
if(!infile)
{
cerr << "open error!" << endl;
exit(1);
}
else cout << "载入成功" << endl;
infile >> player >> ai >> difficulty >> huihe;
mover = player;
for(int i = 1; i <= 8; i++)
for(int j = 1; j <= 8; j++)
infile >> board[i][j];
infile.close();
}
void printmap()//打印棋盘
{
cout << " A B C D E F G H " << endl;
cout << " ┌─┬─┬─┬─┬─┬─┬─┬─┐" << endl;
for(int i = 1; i <= 8; i++)
{
cout << i << "│" ;
for(int j = 1; j <= 8; j++)
{
if(board[i][j] == 0) cout << " ";
if(board[i][j] == 1) cout << "●";
if(board[i][j] == 2) cout << "○";
if(board[i][j] == 3) cout << "×";
cout << "│";
}
if ( i < 8)cout << endl << " ├─┼─┼─┼─┼─┼─┼─┼─┤" << endl;
else cout << endl << " └─┴─┴─┴─┴─┴─┴─┴─┘"<
}
int nplayer = 0, nai = 0;//同时输出比分
for(int i = 1; i<= 8; i++)
for(int j = 1; j<=8; j++)
{
if(board[i][j] == player) nplayer++;
if(board[i][j] == ai) nai++;
}
cout << "ai : player =" << nai << ":" << nplayer << endl;
}
int direction (int x, int y, int dir, int turn, int mode[][13])//判断个方向能吃的棋子个数
{
if ((mode[x + dx[dir]][y + dy[dir]] == 0) || (mode[x + dx[dir]][y + dy[dir]] == 3)) return 0;
if (mode[x + dx[dir]][y + dy[dir]] == turn) return t[dir];
if ((x + dx[dir] < 1) || (x + dx[dir] > 8) || (y + dy[dir] < 1) || (y + dy[dir] > 8)) return 0;
t[dir]++;
return direction(x + dx[dir], y + dy[dir], dir, turn, mode);
}
int sum(int x, int y, int turn,int mode[][13])//计数,放在(x,y)点可吃棋子总数
{
int tep = 0;
for(int i = 0; i <= 7; i++)
{
t[i] = 0;
tep += direction(x, y, i, turn, mode);
}
return tep;
}
void choose()//选择先下还是后下,先下输入1,后下输入2,并且告知棋子颜色
{
char choice;
cout << "请输入你的下棋次序(先下输入1,后下输入2)" << endl;
cin >> choice;
if(choice == '1')
{
player = 1;
ai = 2;
huihe = 1;
cout << "你的棋子:●" << endl;
}
else if(choice == '2')
{
player = 2;
ai = 1;
huihe = 1;
cout << "你的棋子:○" << endl;
}
else
{
cout << "无效的输入,请重新输入" << endl;
choose();
}
cout << "按任意键继续....." << endl;
getch();
system("CLS");
}
int judgepass(int turn, int mode[][13])//判断是否无棋可下,0代表不要pass,1则pass
{
int tep = 0;
for (int i = 1; i <= 8; i++)
{
for (int j = 1; j <= 8; j++)
{
if ((mode[i][j] == 0) && sum(i, j, turn, mode) != 0)
{
tep = 1;
break;
}
}
if(tep) break;
}
if(tep) return 0;
return 1;
}
void reverse(int x, int y, int turn, int mode[][13])//翻转已经被吃掉的棋子
{
for(int l = 0; l <= 7; l++)
{
if(direction(x, y, l, turn, mode) != 0)
for (int i = x + dx[l], j = y + dy[l]; ; i += dx[l], j += dy[l])
{
if (mode[i][j] != turn) mode[i][j] = turn;
else break;
}
}
}
void input(int x, int y, int turn)//输入坐标或者指令
{
if(player == 1) cout << endl << "●";
else cout << endl << "○";
cout << "请输入坐标(先输数字再输字母.例:5c)或指令" <
string order;
cin >> order;
if(order[0] == 's' || order[0] == 'l' || order[0] == 'm' || order[0] == 'r' || order[0] == 'e' || order[0] == 'h'|| order[0] == 'a'|| order[0] == 'g' || order[0] == 'c')
{
switch (order[0])
{
case 's'://s代表save保存
system("CLS");
save();
break;
case 'l'://l代表load读取
system("CLS");
load();
break;
case 'm'://m代表printmap打印棋盘
mark(player);
printmap();
remark();
break;
case 'r'://r代表regret悔棋
system("CLS");
regret();
break;
case 'e'://e代表exit退出
exit(0);
break;
case 'h'://h代表help输出帮助文档
system("CLS");
outputhelp();
//printmap();
break;
case 'a'://a代表again重新开始
system("CLS");
system("reversi.exe");
break;
case 'c':
system("CLS");
break;
case 'g'://g代表giveup认输
cout << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" << endl;
cout << "你认输了!!! ?_?" << endl << endl;
cout << "是否重新开始?(Y/N)" << endl;
char letter;
cin >> letter;
if(letter == 'y')
{
system("CLS");
system("reversi.exe");
}
else exit(0);
break;
}
start();
}
else//输入坐标,先数字后字母
{
x = order[0] - '0';
y = order[1] - 'a' + 1;
if((x >= 1) && (x <= 8) && (y >= 1) && (y <= 8) && ((board[x][y] == 0)||(board[x][y] == 3)) && (sum(x, y, turn, board) != 0))
{
tempsave();
board[x][y] = turn;
reverse(x, y, turn, board);
}
else
{
cout << "无效输入,请重新输入" << endl;
input (x, y , turn);
}
}
}
void tryin(int turn)//电脑ai模拟下棋
{
int max = -1000000, xx = 0, yy = 0;
for(int i = 1; i <= 8; i++)
for(int j = 1; j <= 8; j++)
{
if(max < sum(i, j, turn, boardcopy) + priority[i][j] && ((boardcopy[i][j] == 0) || (boardcopy[i][j] == 3)))
{
max = sum(i, j, turn, boardcopy) + priority[i][j] ;
xx = i;
yy = j;
}
}
boardcopy[xx][yy] = turn;
reverse(xx, yy, turn, boardcopy);
}
int calculate()//计算ai与player得分之差
{
int nplayer = 0, nai = 0;
for(int i = 1; i<= 8; i++)
for(int j = 1; j<=8; j++)
{
if(boardcopy[i][j] == player) nplayer += priority[i][j] ;
if(boardcopy[i][j] == ai) nai += priority[i][j] ;
}
return nai - nplayer;
}
void test (int step)//ai模拟下棋函数
{
if(step == 1)
{
if(!(judgepass(player,boardcopy))) tryin(player);
step ++;
test(step);
return;
}
if((step > 1)&&(step <= difficulty + 10))
{
if(!(judgepass(ai,boardcopy))) tryin(ai);
if(!(judgepass(player,boardcopy))) tryin(player);
step ++;
test(step);
return;
}
return;
}
float prio(int x, int y)//优先级函数
{
for(int i = 1; i <= 8; i++)
for(int j = 1; j<= 8; j++)
boardcopy[i][j] = board[i][j];
int tep = calculate();
if(sum(x,y,ai,boardcopy) != 0)
{
boardcopy[x][y] = ai;
test(1);
return calculate() - tep + priority[x][y];
}
else return 0;
}
void aiinput()//ai输入函数
{
int max = -1000000;
g = 0;
h = 0;
for(int i = 1; i <= 8; i++)
for(int j = 1; j <= 8; j++)
{
if(max < prio(i,j)&&((board[i][j] == 0)||(board[i][j] == 3))&&(sum(i,j,ai,board) != 0))
{
max = prio(i,j);
g = i;
h = j;
}
}
board[g][h] = ai;
reverse(g,h,ai, board);
cout<< "***********************************************" << endl;
cout << endl << "ai将要输入的是" << g ;//ai输入前暂停,让玩家知道ai下棋的位置
putchar(h + 'a' - 1);
cout << endl;
cout << "按任意键继续......" << endl;
getch();
}
void mark(int turn)//标记可以下的位置
{
for(int i = 1; i <= 8; i++)
for(int j = 1; j <= 8; j++)
if((board[i][j] == 0)&&(sum(i,j,turn, board) != 0)) board[i][j] = 3;
}
void remark()//取消棋盘标记
{
for(int i = 1; i <= 8; i++)
for(int j = 1; j <= 8; j++)
if(board[i][j] == 3) board[i][j] = 0;
}
void start ()//游戏开始函数
{
while (true)
{
if((judgepass(ai, board)) && (judgepass(player, board)))//判断游戏是否已经结束
{
printmap();
break;
}
if(mover == player)
{
if(judgepass(player, board))//判断是否是pass
{
huihe++;
cout << " 回合:" << huihe / 2 << " 难度:" << difficulty << endl;
printmap();
cout<
cout << "player pass ~~>_
mover = ai;
cout << "按任意键继续......" << endl;
getch();
system("CLS");
}
else
{
huihe++;
cout << " 回合:" << huihe / 2 << " 难度:" << difficulty << endl;
mark(mover);
printmap();
cout<
remark();
int p, q;
input(p, q, mover);
mover = ai;
system("CLS");
}
}
else
{
if(judgepass(ai, board))//判断是否是pass
{
huihe++;
cout << " 回合:" << huihe / 2 << " 难度:" << difficulty << endl;
printmap();
cout<
cout << "ai pass 0^_^0" << endl;
mover = player;
cout << "按任意键继续......" << endl;
getch();
system("CLS");
}
else
{
huihe++;
cout << " 回合:" << huihe / 2 << " 难度:" << difficulty << endl;
printmap();
aiinput();
mover = player;
system("CLS");
}
}
}
}
void result()//结果函数,用于输出结果
{
tempsave();
int nplayer = 0, nai = 0;
for(int i = 1; i<= 8; i++)
for(int j = 1; j<=8; j++)
{
if(board[i][j] == player) nplayer++;
if(board[i][j] == ai) nai++;
}
cout << "ai : player =" << nai << ":" << nplayer << endl;
if(nai > nplayer) cout <
if(nai < nplayer) cout <
if(nai == nplayer) cout << "平局... @_@" << endl;
}
void choosedifficulty()//选择难度
{
cout << "输入你选择的难度(1~6)" << endl;
cin >> difficulty;
if((difficulty > 6)||(difficulty < 1))
{
cout << "无效输入,请重新输入" << endl;
choosedifficulty();
}
}
void choosemode()//选择模式
{
char mode_choose;
cout << "****************模式选择******************" << endl << endl;
cout << "请选择模式....(输入1或2或3)" << endl << endl;
cout << " 1.新游戏" << endl << endl;
cout << " 2.载入存档" << endl << endl;
cout << " 3.继续上次游戏" << endl;
cin >> mode_choose;
while (true)
{if(!(mode_choose == '1'|| mode_choose == '2'|| mode_choose == '3'))
{
cout << "无效输入,请重新选择..." << endl;
cin >> mode_choose;
}else break;}
switch (mode_choose)
{
case '1':
choosedifficulty();
mover = 1;
choose();
start();
break;
case '2':
system("CLS");
load();
start();
break;
case '3':
regret();
start();
break;
}
}
void tempsave()//临时存档,用于实现悔棋以及继续上次游戏的功能
{
ofstream outfile("tempsave.dat", ios::out);
if(!outfile)
{
cerr << "open error!" << endl;
exit(1);
}
outfile << player << " " << ai << " " << difficulty << " " << huihe << endl;
for(int i = 1; i <= 8; i++)
for(int j = 1; j <= 8; j++)
outfile << board[i][j] << " ";
outfile.close();
}
void regret()//悔棋函数,读取上一步的临时存档
{
ifstream infile("tempsave.dat", ios::in);
if(!infile)
{
cerr << "open error!" << endl;
exit(1);
}
else cout << "载入成功" << endl;
infile >> player >> ai >> difficulty >> huihe;
mover = player;
for(int i = 1; i <= 8; i++)
for(int j = 1; j <= 8; j++)
infile >> board[i][j];
infile.close();
}
void outputhelp()//输出帮助文档
{
cout << "********************帮助*******************" << endl << endl;
cout << "指令一览:(输入指令时只需输入对应字母后回车)" <
cout << " s --> 存盘 | l --> 读盘" << endl;
cout << " r --> 悔棋 | e --> 退出" << endl;
cout << " g --> 认输 | a --> 重来" << endl;
cout << " h --> 帮助 | c --> 清屏" << endl << endl;
cout << "说明: " << endl;
cout << " ×代表你可以下的位置" << endl;
cout << " 本游戏仅允许一次悔棋" << endl;
cout << " 所有输入的字母(指令或坐标)均为小写" << endl ;
cout << " 请勿更改exe文件名(reversi)" << endl;
cout << " 请勿随意删除两个dat文件" << endl << endl;
cout << "按任意键继续......" << endl;
getch();
system("CLS");
}