五子棋用了两个类,一个棋盘类ChessBoard和一个玩家类Player,然后用一个game类包装一下,实现一些游戏的基本操作。
ChessBoard.h:
#ifndef _CHESS_BOARD_H
#define _CHESS_BOARD_H
#include<vector>
#include<string>
#include<iostream>
class ChessBoard
{
public:
ChessBoard(std::size_t board_size);
void PrintChessBoard()const;
std::size_t ChessmanNumbers()const{ return ChessmanNum; }
std::size_t Size()const{ return BoardSize; }
void SetBoardSize(std::size_t boardsize){ BoardSize = boardsize; }
bool CheckFull()const{ return ChessmanNum == BoardSize * BoardSize; }
bool AddChessman(std::size_t x, std::size_t y, std::string color);
bool CheckPosition(std::size_t x, std::size_t y)const;
private:
std::vector<std::string> Board;//棋盘,用制表符和圆圈表示
std::size_t ChessmanNum;//棋子数
std::size_t BoardSize;//棋盘大小
};
//┌ └ ┐ ┘ ─ │ ├ ┤ ┬ ┴ ┼ ○ ●
#endif
Player.h
#ifndef _PLAYER_H
#define _PLAYER_H
#include"ChessBoard.h"
class player
{
public:
player(const std::string&name = "Player",
std::string chessman_type = "棋",
ChessBoard* board = nullptr) :
CB(board),
ChessmanType(chessman_type),
PlayerName(name),
MaxLength(0),
Chessmans()
{
if (board)SetChessmans();
}
virtual ~player(){}
virtual void SetChessBoard(ChessBoard *cbp);
bool Win()const{ return MaxLength >= 5; }
const std::string& Name()const{ return PlayerName; }
virtual void AddChessman();
void SetName(const std::string &name);
void SetChessmanType(char chessmantype);
virtual void SetOpponent(std::vector<std::vector<std::vector<int>>>*){};
std::vector<std::vector<std::vector<int>>> *
GetChessmans(){ return &Chessmans; }
protected:
ChessBoard *CB;<span style="white-space:pre"> </span>//棋盘指针
std::string ChessmanType;<span style="white-space:pre"> </span>//棋子样式
std::string PlayerName;<span style="white-space:pre"> </span>//玩家姓名
std::size_t MaxLength;<span style="white-space:pre"> </span>//目前状态下最长的连子数,大于等于5时就获胜
std::vector<std::vector<std::vector<int>>> Chessmans;//棋子状态,三维数组,前两维代表坐标,最后一维长度为4,代表该坐标位置的四个方向的连子数
void update(std::size_t x, std::size_t y);
bool CheckPosition(std::size_t,std::size_t)const;
void SetChessmans();
};
#endif
Game.h
#ifndef _GANME_H
#define _GAME_H
#include"ChessBoard.h"
#include"player.h"
#include"AI.h"
class Game
{
public:
Game(player*player1, player*player2, std::size_t board_size = 16) :
CB(board_size), p1(player1), p2(player2) {
p1->SetChessBoard(&CB);
p2->SetChessBoard(&CB);
p1->SetOpponent(p2->GetChessmans());
p2->SetOpponent(p1->GetChessmans());
}
~Game(){ }
void GameSet();
void SetPlayerName(std::size_t);
void SetPlayerChessmanType(std::size_t);
void SetBoardSize();
void StartGame();
void EndGame(std::size_t);
bool GameOver()const{ return p1->Win() ||
p2->Win() ||
CB.CheckFull();
<span style="white-space:pre"> </span> }
private:
ChessBoard CB;<span style="white-space:pre"> </span>//棋盘
player *p1, *p2;//玩家指针
void UpdateBoard(std::size_t)const;
};
#endif
然后是实现:
ChessBoard.cpp
#include"ChessBoard.h"
ChessBoard::ChessBoard(std::size_t board_size)
{
ChessmanNum = 0;
BoardSize = board_size;
Board.push_back(std::string("┌"));
for (int i = 1; i <= BoardSize; ++i)
Board[0] += "┬";
Board[0] += "┐";
for (int i = 1; i <= BoardSize; ++i){
Board.push_back(std::string("├"));
for (int j = 1; j <= BoardSize; ++j)
Board[i] += "┼";
Board[i] += "┤";
}
Board.push_back(std::string("└"));
for (int i = 1; i <= BoardSize; ++i)
Board[BoardSize + 1] += "┴";
Board[BoardSize + 1] += "┘";
}
void ChessBoard::PrintChessBoard()const{
std::cout << "\t\t\t ";
for (int i = 0; i <= BoardSize; ++i)
std::cout << i % 10 << ' ';
std::cout << std::endl;
int rownum = 0;
for (auto const&s : Board)
std::cout << "\t\t\t" << rownum++ % 10 << ' ' << s << std::endl;
}
bool ChessBoard::CheckPosition(std::size_t x, std::size_t y) const
{
if (x < 1 || x > BoardSize || y < 1 || y > BoardSize)
return false;
std::string s = "┼";
if (Board[x][y * 2] != s[0] && Board[x][y * 2 + 1] != s[1])
return false;
return true;
}
bool ChessBoard::AddChessman(std::size_t x, std::size_t y, std::string color)
{
if (!CheckPosition(x, y))
return false;
Board[x][y * 2] = color[0];
Board[x][y * 2 + 1] = color[1];
++ChessmanNum;
return true;
}
//┌ └ ┐ ┘ ─ │ ├ ┤ ┬ ┴ ┼ ○ ●
Player.cpp
#include"player.h"
void player::AddChessman(){
std::size_t x = 0, y = 0;
while (true){
try{
std::cin >> x >> y;
if (!std::cin || !CB->AddChessman(x, y, ChessmanType)){
throw std::runtime_error("无效坐标");
}
else{
update(x, y);
break;
}
}catch (std::runtime_error re){
system("cls");
CB->PrintChessBoard();
std::cout << re.what() << ",请重新输入:";
std::cin.clear();
std::cin.sync();
}
}
}
void player::SetName(const std::string &name){
PlayerName = name;
}
void player::SetChessmanType(char chessmantype){
ChessmanType = chessmantype;
}
void player::SetChessBoard(ChessBoard *cbp){
CB = cbp;
SetChessmans();
}
void player::SetChessmans()
{
Chessmans = std::vector<std::vector<std::vector<int>>>(
CB->Size() + 2, std::vector<std::vector<int>>(
CB->Size() + 2, std::vector<int>(4, 0)));
}
bool player::CheckPosition(std::size_t x, std::size_t y)const
{
if (x > CB->Size() || y > CB->Size())
return false;
if (x < 1 || y < 1)return false;
return true;
}
void player::update(std::size_t x, std::size_t y)<span style="white-space:pre"> </span>//更新己方棋盘状态
{
std::pair<std::size_t, std::size_t> dp[4] = {
{ -1, 1 }, { 0, 1 }, { 1, 1 }, { 1, 0 }
};
for (int i = 0; i != 4; ++i){
Chessmans[x][y][i] = Chessmans[x + dp[i].first][y + dp[i].second][i] +
Chessmans[x - dp[i].first][y - dp[i].second][i] + 1;
std::size_t step = 1;
while (CheckPosition(x + step * dp[i].first, y + step * dp[i].second) &&
Chessmans[x + step * dp[i].first][y + step * dp[i].second][i]){
Chessmans[x + step * dp[i].first][y + step * dp[i].second][i] = Chessmans[x][y][i];
++step;
}
step = -1;
while (CheckPosition(x + step * dp[i].first, y + step * dp[i].second) &&
Chessmans[x + step * dp[i].first][y + step * dp[i].second][i]){
Chessmans[x + step * dp[i].first][y + step * dp[i].second][i] = Chessmans[x][y][i];
--step;
}
MaxLength = MaxLength < Chessmans[x][y][i] ? Chessmans[x][y][i] : MaxLength;
}
}
game.cpp
#include"Game.h"
#include"AI.h"
void Game::GameSet()
{
std::cout << "\t\t\t 设置" << std::endl;
std::cout << "\t\t\t1>p1姓名" << std::endl;
std::cout << "\t\t\t2>p2姓名" << std::endl;
std::cout << "\t\t\t3>p1棋子样式" << std::endl;
std::cout << "\t\t\t4>p2棋子样式" << std::endl;
std::cout << "\t\t\t5>棋盘大小" << std::endl;
std::cout << "\t\t\t6>退出" << std::endl;
std::size_t ch;
std::cin >> ch;
switch (ch){
case 1:SetPlayerName(1); break;
case 2:SetPlayerName(2); break;
case 3:SetPlayerChessmanType(1); break;
case 4:SetPlayerChessmanType(2); break;
case 5:SetBoardSize(); break;
case 6:break;
default:std::cout << "请输入数字1~5" << std::endl; break;
}
}
void Game::SetPlayerName(std::size_t PlayerNum)
{
std::cout << "请输入玩家姓名:";
std::string name;
std::cin >> name;
PlayerNum == 1 ? p1->SetName(name) : p2->SetName(name);
}
void Game::SetPlayerChessmanType(std::size_t PlayerNum)
{
std::cout << "请输入棋子样式:";
char ChessmanType;
std::cin >> ChessmanType;
PlayerNum == 1 ?
p1->SetChessmanType(ChessmanType) :
p2->SetChessmanType(ChessmanType);
}
void Game::SetBoardSize()
{
std::cout << "请输入棋盘大小:";
std::size_t size;
std::cin >> size;
CB.SetBoardSize(size);
}
void Game::StartGame()
{
bool p1turn = true;
UpdateBoard(1);
while (!GameOver()){
if (p1turn){
p1->AddChessman();
p1turn = false;
UpdateBoard(2);
}
else{
p2->AddChessman();
p1turn = true;
UpdateBoard(1);
}
}
EndGame(p1->Win() ? 1 : (p2->Win() ? 2 : 3));
}
void Game::EndGame(std::size_t PlayerNum)
{
system("cls");
CB.PrintChessBoard();
if (PlayerNum == 3){
std::cout << "\t\t\t和棋!" << std::endl;
return;
}
std::cout << "\t\t\t"
<< (PlayerNum == 1 ? p1->Name() : p2->Name())
<< "获胜!" << std::endl;
}
void Game::UpdateBoard(std::size_t PlayerNum)const
{
system("cls");
CB.PrintChessBoard();
std::cout << "\t\t\t"
<< (PlayerNum == 1 ? p1->Name() : p2->Name())
<< "请落子:";
}
其实我觉得用vector<string>保存棋盘状态挺蠢的。。。用数组保存就好了,后面在print函数中转换之后输出就好了。
再就是自己跟着想法随便实现了一个简单的AI的类,继承自Player,积分制,遍历棋盘所有坐标,计算威胁值和有利值,加权一下选择最优的坐标落子
AI.h
#ifndef _AI_H
#define _AI_H
#include"player.h"
class AIplayer : public player
{
public:
AIplayer(const std::string&name,
std::string chessman_type = "AI",
ChessBoard* board = nullptr) :
player(name, chessman_type, board)
{
if (board)SetScore();
}
void SetOpponent(std::vector<
std::vector<std::vector<int>>>* opp)
{ opponent = opp; }
void AddChessman() override;
void SetChessBoard(ChessBoard*) override;
void SetScore();
virtual ~AIplayer()override { player::~player(); }
private:
std::vector<std::vector<std::vector<int>>>* opponent;
std::vector<std::vector<double>> Score;
bool CheckPosition(std::size_t x, std::size_t y,bool MyTurn){
if (OutOfBoard(x,y)) return false;
if (MyTurn && (*opponent)[x][y][0])
return false;
else if (Chessmans[x][y][0])
return false;
return true;
}
bool OutOfBoard(std::size_t x, std::size_t y){
if (x<1 || y<1 || x>CB->Size() || y>CB->Size())
return true;
return false;
}
double GetThreaten(std::size_t,std::size_t);
double GetChance(std::size_t, std::size_t);
std::pair < std::size_t, std::size_t >
UpdateScore();
bool MyChessman(std::size_t, std::size_t);
bool Five(std::vector<std::vector<std::vector<int>>>*,
std::vector<std::vector<std::vector<int>>>*,
std::size_t, std::size_t); //1000
bool FourOrDooubleThree(std::vector<std::vector<std::vector<int>>>*,
std::vector<std::vector<std::vector<int>>>*,
std::size_t, std::size_t); //500
bool ThreeOrTwoTwo(std::vector<std::vector<std::vector<int>>>*,
std::vector<std::vector<std::vector<int>>>*,
std::size_t, std::size_t); //250
bool TwoOrOneOne(std::vector<std::vector<std::vector<int>>>*,
std::vector<std::vector<std::vector<int>>>*,
std::size_t, std::size_t); //100
bool OneOrZeroZero(std::vector<std::vector<std::vector<int>>>*,
std::vector<std::vector<std::vector<int>>>*,
std::size_t, std::size_t); //50
std::size_t AliveN(std::vector<std::vector<std::vector<int>>>*,
std::vector<std::vector<std::vector<int>>>*,
std::size_t, std::size_t, std::size_t);
std::size_t DeathN(std::vector<std::vector<std::vector<int>>>*,
std::vector<std::vector<std::vector<int>>>*,
std::size_t, std::size_t, std::size_t);
};
#endif
#include"AI.h"
void AIplayer::AddChessman()
{
std::pair<std::size_t, std::size_t>
pos = UpdateScore();
CB->AddChessman(pos.first, pos.second, ChessmanType);
update(pos.first, pos.second);
}
void AIplayer::SetScore(){
Score = std::vector<std::vector<double>>(
CB->Size() + 2, std::vector<double>(CB->Size() + 2, 0.0)
);
}
void AIplayer::SetChessBoard(ChessBoard*CB){
player::SetChessBoard(CB);
SetScore();
}
std::pair<std::size_t, std::size_t>
AIplayer::UpdateScore(){
std::size_t Xpos = (CB->Size() + 1) / 2, Ypos = Xpos;
for (std::size_t x = 1; x <= CB->Size(); ++x){
for (std::size_t y = 1; y <= CB->Size(); ++y){
Score[x][y] = GetThreaten(x, y) + 1.1 * GetChance(x, y);//威胁值和有利值加权,己方的权值略高,所以会有一点攻击性
if (Score[x][y] > Score[Xpos][Ypos])
Xpos = x, Ypos = y;
}
}
return { Xpos, Ypos };
}
double AIplayer::GetThreaten(std::size_t x, std::size_t y)
{
if (Chessmans[x][y][0] ||
(*opponent)[x][y][0])
return 0.0;
if (Five(opponent, &Chessmans, x, y))
return 1000;
if (FourOrDooubleThree(opponent, &Chessmans, x, y))
return 500;
if (ThreeOrTwoTwo(opponent, &Chessmans, x, y))
return 250;
if (TwoOrOneOne(opponent, &Chessmans, x, y))
return 50;
if (OneOrZeroZero(opponent, &Chessmans, x, y))
return 5;
return 0;
}
double AIplayer::GetChance(std::size_t x, std::size_t y)
{
if ((*opponent)[x][y][0] ||
Chessmans[x][y][0])
return 0.0;
if (Five(&Chessmans, opponent, x, y))
return 10000;
if (FourOrDooubleThree(&Chessmans, opponent, x, y))
return 500;
if (ThreeOrTwoTwo(&Chessmans, opponent, x, y))
return 250;
if (TwoOrOneOne(&Chessmans, opponent, x, y))
return 50;
if (OneOrZeroZero(&Chessmans, opponent, x, y))
return 5;
return 0;
}
bool AIplayer::MyChessman(std::size_t x, std::size_t y)
{
return Chessmans[x][y][0] != 0;
}
bool AIplayer::Five(std::vector<std::vector<std::vector<int>>>*Opp,
std::vector<std::vector<std::vector<int>>>*Che,
std::size_t x, std::size_t y) //1000
{
std::pair<std::size_t, std::size_t> pos[4] = {
{ -1, 1 }, { 0, 1 }, { 1, 1 }, { 1, 0 }
};
std::size_t CountFoure = 0;
for (int i = 0; i != 4; ++i){
if ((*Opp)[x + pos[i].first][y + pos[i].second][i] +
(*Opp)[x - pos[i].first][y - pos[i].second][i] + 1 >= 5){
return true;
}
if ((*Opp)[x + pos[i].first][y + pos[i].second][i] +
(*Opp)[x - pos[i].first][y - pos[i].second][i] + 1 == 4)
++CountFoure;
}
if (CountFoure > 1)
return true;
return false;
}
bool AIplayer::FourOrDooubleThree(std::vector<std::vector<std::vector<int>>>*Opp,
std::vector<std::vector<std::vector<int>>>*Che,
std::size_t x, std::size_t y) //500
{
std::pair<std::size_t, std::size_t> pos[4] = {
{ -1, 1 }, { 0, 1 }, { 1, 1 }, { 1, 0 }
};
std::size_t CountThree = 0;
for (int i = 0; i != 4; ++i){
auto lhs = (*Opp)[x + pos[i].first][y + pos[i].second][i];
auto rhs = (*Opp)[x - pos[i].first][y - pos[i].second][i];
if (rhs + lhs + 1 == 4 &&
!OutOfBoard(x + (lhs + 1)*pos[i].first, y + (lhs + 1)*pos[i].second) &&
!(*Che)[x + (lhs + 1)*pos[i].first][y + (lhs + 1)*pos[i].second][0] &&
!OutOfBoard(x - (rhs + 1)*pos[i].first, y - (rhs + 1)*pos[i].second) &&
!(*Che)[x - (rhs + 1)*pos[i].first][y - (rhs + 1)*pos[i].second][0])
return true;
if (rhs + lhs + 1 == 3 &&
!OutOfBoard(x + (lhs + 1)*pos[i].first, y + (lhs + 1)*pos[i].second) &&
!(*Che)[x + (lhs + 1)*pos[i].first][y + (lhs + 1)*pos[i].second][0] &&
!OutOfBoard(x - (rhs + 1)*pos[i].first, y - (rhs + 1)*pos[i].second) &&
!(*Che)[x - (rhs + 1)*pos[i].first][y - (rhs + 1)*pos[i].second][0])
++CountThree;
if (rhs + lhs + 1 == 4 &&
(((OutOfBoard(x + (lhs + 1)*pos[i].first, y + (lhs + 1)*pos[i].second) ||
(*Che)[x + (lhs + 1)*pos[i].first][y + (lhs + 1)*pos[i].second][0]) &&
!OutOfBoard(x - (rhs + 1)*pos[i].first, y - (rhs + 1)*pos[i].second) &&
!(*Che)[x - (rhs + 1)*pos[i].first][y - (rhs + 1)*pos[i].second][0]) ||
(!OutOfBoard(x + (lhs + 1)*pos[i].first, y + (lhs + 1)*pos[i].second) &&
!(*Che)[x + (lhs + 1)*pos[i].first][y + (lhs + 1)*pos[i].second][0] &&
(OutOfBoard(x - (rhs + 1)*pos[i].first, y - (rhs + 1)*pos[i].second) ||
(*Che)[x - (rhs + 1)*pos[i].first][y - (rhs + 1)*pos[i].second][0]))))
++CountThree;
}
if (CountThree > 1)
return true;
return false;
}
bool AIplayer::ThreeOrTwoTwo(std::vector<std::vector<std::vector<int>>>*Opp,
std::vector<std::vector<std::vector<int>>>*Che,
std::size_t x, std::size_t y) //250
{
std::pair<std::size_t, std::size_t> pos[4] = {
{ -1, 1 }, { 0, 1 }, { 1, 1 }, { 1, 0 }
};
std::size_t CountTwo = 0;
for (int i = 0; i != 4; ++i){
auto lhs = (*Opp)[x + pos[i].first][y + pos[i].second][i];
auto rhs = (*Opp)[x - pos[i].first][y - pos[i].second][i];
if (rhs + lhs + 1 == 4 &&
(((OutOfBoard(x + (lhs + 1)*pos[i].first, y + (lhs + 1)*pos[i].second) ||
(*Che)[x + (lhs + 1)*pos[i].first][y + (lhs + 1)*pos[i].second][0]) &&
!OutOfBoard(x - (rhs + 1)*pos[i].first, y - (rhs + 1)*pos[i].second) &&
!(*Che)[x - (rhs + 1)*pos[i].first][y - (rhs + 1)*pos[i].second][0]) ||
(!OutOfBoard(x + (lhs + 1)*pos[i].first, y + (lhs + 1)*pos[i].second) &&
!(*Che)[x + (lhs + 1)*pos[i].first][y + (lhs + 1)*pos[i].second][0] &&
(OutOfBoard(x - (rhs + 1)*pos[i].first, y - (rhs + 1)*pos[i].second) ||
(*Che)[x - (rhs + 1)*pos[i].first][y - (rhs + 1)*pos[i].second][0]))))
return true;
if (rhs + lhs + 1 == 3 &&
!OutOfBoard(x + (lhs + 1)*pos[i].first, y + (lhs + 1)*pos[i].second) &&
!(*Che)[x + (lhs + 1)*pos[i].first][y + (lhs + 1)*pos[i].second][0] &&
!OutOfBoard(x - (rhs + 1)*pos[i].first, y - (rhs + 1)*pos[i].second) &&
!(*Che)[x - (rhs + 1)*pos[i].first][y - (rhs + 1)*pos[i].second][0])
return true;
if (rhs + lhs + 1 == 2 &&
!OutOfBoard(x + (lhs + 1)*pos[i].first, y + (lhs + 1)*pos[i].second) &&
!(*Che)[x + (lhs + 1)*pos[i].first][y + (lhs + 1)*pos[i].second][0] &&
!OutOfBoard(x - (rhs + 1)*pos[i].first, y - (rhs + 1)*pos[i].second) &&
!(*Che)[x - (rhs + 1)*pos[i].first][y - (rhs + 1)*pos[i].second][0])
++CountTwo;
if (rhs + lhs + 1 == 3 &&
(((OutOfBoard(x + (lhs + 1)*pos[i].first, y + (lhs + 1)*pos[i].second) ||
(*Che)[x + (lhs + 1)*pos[i].first][y + (lhs + 1)*pos[i].second][0]) &&
!OutOfBoard(x - (rhs + 1)*pos[i].first, y - (rhs + 1)*pos[i].second) &&
!(*Che)[x - (rhs + 1)*pos[i].first][y - (rhs + 1)*pos[i].second][0]) ||
(!OutOfBoard(x + (lhs + 1)*pos[i].first, y + (lhs + 1)*pos[i].second) &&
!(*Che)[x + (lhs + 1)*pos[i].first][y + (lhs + 1)*pos[i].second][0] &&
(OutOfBoard(x - (rhs + 1)*pos[i].first, y - (rhs + 1)*pos[i].second) ||
(*Che)[x - (rhs + 1)*pos[i].first][y - (rhs + 1)*pos[i].second][0]))))
++CountTwo;
}
if (CountTwo > 1)
return true;
return false;
}
bool AIplayer::TwoOrOneOne(std::vector<std::vector<std::vector<int>>>*Opp,
std::vector<std::vector<std::vector<int>>>*Che,
std::size_t x, std::size_t y) //100
{
std::pair<std::size_t, std::size_t> pos[4] = {
{ -1, 1 }, { 0, 1 }, { 1, 1 }, { 1, 0 }
};
for (int i = 0; i != 3; ++i){
auto lhs = (*Opp)[x + pos[i].first][y + pos[i].second][i];
auto rhs = (*Opp)[x - pos[i].first][y - pos[i].second][i];
if (rhs + lhs + 1 == 3 &&
(((OutOfBoard(x + (lhs + 1)*pos[i].first, y + (lhs + 1)*pos[i].second) ||
(*Che)[x + (lhs + 1)*pos[i].first][y + (lhs + 1)*pos[i].second][0]) &&
!OutOfBoard(x - (rhs + 1)*pos[i].first, y - (rhs + 1)*pos[i].second) &&
!(*Che)[x - (rhs + 1)*pos[i].first][y - (rhs + 1)*pos[i].second][0]) ||
(!OutOfBoard(x + (lhs + 1)*pos[i].first, y + (lhs + 1)*pos[i].second) &&
!(*Che)[x + (lhs + 1)*pos[i].first][y + (lhs + 1)*pos[i].second][0] &&
(OutOfBoard(x - (rhs + 1)*pos[i].first, y - (rhs + 1)*pos[i].second) ||
(*Che)[x - (rhs + 1)*pos[i].first][y - (rhs + 1)*pos[i].second][0]))))
return true;
if (rhs + lhs + 1 == 2 &&
!OutOfBoard(x + (lhs + 1)*pos[i].first, y + (lhs + 1)*pos[i].second) &&
!(*Che)[x + (lhs + 1)*pos[i].first][y + (lhs + 1)*pos[i].second][0] &&
!OutOfBoard(x - (rhs + 1)*pos[i].first, y - (rhs + 1)*pos[i].second) &&
!(*Che)[x - (rhs + 1)*pos[i].first][y - (rhs + 1)*pos[i].second][0])
return true;
}
return false;
}
bool AIplayer::OneOrZeroZero(std::vector<std::vector<std::vector<int>>>*Opp,
std::vector<std::vector<std::vector<int>>>*Che,
std::size_t x, std::size_t y) //5
{
std::pair<std::size_t, std::size_t> pos[4] = {
{ -1, 1 }, { 0, 1 }, { 1, 1 }, { 1, 0 }
};
for (int i = 0; i != 4; ++i){
auto lhs = (*Opp)[x + pos[i].first][y + pos[i].second][i];
auto rhs = (*Opp)[x - pos[i].first][y - pos[i].second][i];
if (rhs + lhs + 1 == 2 &&
(((OutOfBoard(x + (lhs + 1)*pos[i].first, y + (lhs + 1)*pos[i].second) ||
(*Che)[x + (lhs + 1)*pos[i].first][y + (lhs + 1)*pos[i].second][0]) &&
!OutOfBoard(x - (rhs + 1)*pos[i].first, y - (rhs + 1)*pos[i].second) &&
!(*Che)[x - (rhs + 1)*pos[i].first][y - (rhs + 1)*pos[i].second][0]) ||
(!OutOfBoard(x + (lhs + 1)*pos[i].first, y + (lhs + 1)*pos[i].second) &&
!(*Che)[x + (lhs + 1)*pos[i].first][y + (lhs + 1)*pos[i].second][0] &&
(OutOfBoard(x - (rhs + 1)*pos[i].first, y - (rhs + 1)*pos[i].second) ||
(*Che)[x - (rhs + 1)*pos[i].first][y - (rhs + 1)*pos[i].second][0]))))
return true;
}
return false;
}
std::size_t AIplayer::AliveN(std::vector<std::vector<std::vector<int>>>*Opp,
std::vector<std::vector<std::vector<int>>>*Che,
std::size_t x, std::size_t y, std::size_t n)
{
std::size_t Count = 0;
std::pair<std::size_t, std::size_t> pos[4] = {
{ -1, 0 }, { 0, 1 }, { 1, 1 }, { 1, 0 }
};
for (int i = 0; i != 4; ++i){
auto lhs = (*Opp)[x + pos[i].first][y + pos[i].second][i];
auto rhs = (*Opp)[x - pos[i].first][y - pos[i].second][i];
if (lhs + rhs + 1 == n &&
!OutOfBoard(x + (lhs + 1)*pos[i].first, y + (lhs + 1)*pos[i].second) &&
!(*Che)[x + (lhs + 1)*pos[i].first][y + (lhs + 1)*pos[i].second][0] &&
!OutOfBoard(x - (rhs + 1)*pos[i].first, y - (rhs + 1)*pos[i].second) &&
!(*Che)[x - (rhs + 1)*pos[i].first][y - (rhs + 1)*pos[i].second][0])
++Count;
}
return Count;
}
std::size_t AIplayer::DeathN(std::vector<std::vector<std::vector<int>>>*Opp,
std::vector<std::vector<std::vector<int>>>*Che,
std::size_t x, std::size_t y, std::size_t n)
{
std::size_t Count = 0;
std::pair<std::size_t, std::size_t> pos[4] = {
{ -1, 0 }, { 0, 1 }, { 1, 1 }, { 1, 0 }
};
for (int i = 0; i != 4; ++i){
auto lhs = (*Opp)[x + pos[i].first][y + pos[i].second][i];
auto rhs = (*Opp)[x - pos[i].first][y - pos[i].second][i];
int llhs = 0, rrhs = 0;
if (!OutOfBoard(x + 2 * pos[i].first, y + 2 * pos[i].second)&&
!(*Che)[x + 2 * pos[i].first][y + 2 * pos[i].second][0])
llhs = (*Opp)[x + 2 * pos[i].first][y + 2 * pos[i].second][i];
if (!OutOfBoard(x - 2 * pos[i].first, y - 2 * pos[i].second)&&
!(*Che)[x - 2 * pos[i].first][y - 2 * pos[i].second][0])
rrhs = (*Opp)[x - 2 * pos[i].first][y - 2 * pos[i].second][i];
if (rhs + lhs + 1 == n &&
(((OutOfBoard(x + (lhs + 1)*pos[i].first, y + (lhs + 1)*pos[i].second) ||
(*Che)[x + (lhs + 1)*pos[i].first][y + (lhs + 1)*pos[i].second][0]) &&
!OutOfBoard(x - (rhs + 1)*pos[i].first, y - (rhs + 1)*pos[i].second) &&
!(*Che)[x - (rhs + 1)*pos[i].first][y - (rhs + 1)*pos[i].second][0]) ||
(!OutOfBoard(x + (lhs + 1)*pos[i].first, y + (lhs + 1)*pos[i].second) &&
!(*Che)[x + (lhs + 1)*pos[i].first][y + (lhs + 1)*pos[i].second][0] &&
(OutOfBoard(x - (rhs + 1)*pos[i].first, y - (rhs + 1)*pos[i].second) ||
(*Che)[x - (rhs + 1)*pos[i].first][y - (rhs + 1)*pos[i].second][0]))))
{++Count; continue;}
if (lhs == 0 && llhs && llhs + rhs + 1 == n &&
!OutOfBoard(x + pos[i].first, y + pos[i].second) &&
!(*Che)[x + pos[i].first][y + pos[i].second][0] &&
!OutOfBoard(x + (llhs + 2)*pos[i].first, y + (llhs + 2)*pos[i].second) &&
!(*Che)[x + (llhs + 2)*pos[i].first][y + (llhs + 2)*pos[i].second][0] &&
!OutOfBoard(x - (rhs + 1)*pos[i].first, y - (rhs + 1)*pos[i].second) &&
!(*Che)[x - (rhs + 1)*pos[i].first][y - (rhs + 1)*pos[i].second][0])
{++Count; continue;}
if (rhs == 0 && rrhs && rrhs + lhs + 1 == n &&
!OutOfBoard(x + pos[i].first, y + pos[i].second) &&
!(*Che)[x + pos[i].first][y + pos[i].second][0] &&
!OutOfBoard(x + (lhs + 1)*pos[i].first, y + (lhs + 1)*pos[i].second) &&
!(*Che)[x + (lhs + 1)*pos[i].first][y + (lhs + 1)*pos[i].second][0] &&
!OutOfBoard(x - (rrhs + 2)*pos[i].first, y - (rrhs + 2)*pos[i].second) &&
!(*Che)[x - (rrhs + 2)*pos[i].first][y - (rrhs + 2)*pos[i].second][0])
++Count;
}
return Count;
}
//不要问我后面 if 里面一坨一坨的是什么鬼。。。我当时就是跟着自己的思维写的判断是否超出棋盘和是否该坐标已经有子。。。后面我有尝试单独放进一个函数里面,,,但是失败了,,,真的太丑了。
食用方法:‘
main.cpp
#include"Game.h"
int main()
{
AIplayer p1("Captian America", "○"); //AI玩家
//player p1("Captian America", "○"); //对战玩家
player p2("Iron Man", "●");
Game game(&p1,&p2);
game.StartGame();
return 0;
}
大概就是这样子。没有去专门学习AI算法,自己跟着想法简单写的,比较丑。