Untitled
unknown
plain_text
3 years ago
11 kB
13
Indexable
#include <iostream> #include <fstream> #include <cstdlib> #include <ctime> #include <array> #include <set> #include <algorithm> #define top 2 using namespace std; int alpha_beta(int depth, int alpha, int beta, bool maximize,set<pair<int,int>> next_move, int cc); void write_valid_spot(std::ofstream& fout); int evaluate(); enum SPOT_STATE { EMPTY = 0, BLACK = 1, WHITE = 2, TMP_B = 3, TMP_W = 4 }; const int SIZE = 15; std::array<std::array<int, SIZE>, SIZE> board; int c; int K[4]={1,0,1,1}; int T[4]={1,1,0,-1}; pair<int,int> play; int player; int opponent; void read_board(std::ifstream& fin) { fin >> player; for (int i = 0; i < SIZE; i++) { for (int j = 0; j < SIZE; j++) { fin >> board[i][j]; } } } /*void write_valid_spot(std::ofstream& fout) { srand(time(NULL)); int x, y; // Keep updating the output until getting killed. while(true) { // Choose a random spot. int x = (rand() % SIZE); int y = (rand() % SIZE); if (board[x][y] == EMPTY) { fout << x << " " << y << std::endl; // Remember to flush the output to ensure the last action is written to file. fout.flush(); } } }*/ int main(int, char** argv) { std::ifstream fin(argv[1]); std::ofstream fout(argv[2]); read_board(fin); write_valid_spot(fout); fin.close(); fout.close(); return 0; } int alpha_beta(int d, int alpha, int beta, bool maximize,set<pair<int,int>> next_move, int cc){ if(d == 0) return evaluate(); if(maximize){ int value = -10000; for(auto i:next_move){ board[i.first][i.second] = player+2; set<pair<int,int>> next(next_move); for(int s = i.first-1; s<=i.first+1; s++){ for(int b = i.second-1; b<=i.second+1; b++){ if(s>=0 && s<SIZE && b>=0 && b<SIZE && board[s][b] == EMPTY){ next.insert(make_pair(s,b)); } } } next.erase(i); int temp = alpha_beta( d-1, alpha,beta, false, next, cc+1); if(temp>value){ value = temp; if(d==top) play = make_pair(i.first,i.second); } //value = max(value,temp); alpha = max(alpha,value); board[i.first][i.second] = EMPTY; if(alpha>=beta)break; } return value; } else{ int value = 10000; for(auto i:next_move){ board[i.first][i.second] = opponent+2; set<pair<int,int>> next(next_move); for(int s = i.first-1; s<=i.first+1; s++){ for(int b = i.second-1; b<=i.second+1; b++){ if(s>=0 && s<SIZE && b>=0 && b<SIZE && board[s][b] == EMPTY){ next.insert(make_pair(s,b)); } } } next.erase(i); value = min(value,alpha_beta( d-1, alpha, beta, true, next,cc+1)); beta = min(beta,value); board[i.first][i.second] = EMPTY; if(beta<=alpha)break; } return value; } } void write_valid_spot(std::ofstream& fout){ c=0; if(player == BLACK) opponent = WHITE; else opponent = BLACK; set<pair<int,int>> next_move; for(int i = 0; i<SIZE; i++){ for(int j = 0; j<SIZE; j++){ if(board[i][j] != EMPTY ){ if(board[i][j] == player ) c++; for(int s = i-1; s<=i+1; s++){ for(int b = j-1; b<=j+1; b++){ if(s>=0 && s<SIZE && b>=0 && b<SIZE && board[s][b] == EMPTY){ next_move.insert(make_pair(s,b)); } } } } } } cout<<c<<endl; if(next_move.empty()){ fout <<7 << " " << 7 << std::endl; fout.flush(); }else if(c<=1){ int k; for(int i = 0; i<SIZE; i++){ for(int j = 0; j<SIZE; j++){ if(board[i][j] == opponent) { k=j; break; } } } if( k >= 7) fout <<7 << " " << 6 << std::endl; else fout <<7 << " " << 8 << std::endl; fout.flush(); } else{ alpha_beta(top,-10000,10000,1,next_move,c); fout << play.first << " " << play.second << std::endl; fout.flush(); } } int evaluate(){ //std::array<std::array<int, SIZE>, SIZE> new_board = board; int x,y,k,t; int count; int stuck; //檢查xoooo這類被夾住的 int value; for( int i=0; i<SIZE; i++){ for( int j=0; j<SIZE; j++){ //玩家value if( board[i][j] == player+2 || board[i][j] == player ){ //player+2為玩家假設會下的棋 for(int q=0; q<4; q++){ k=K[q]; //向量 t=T[q]; //向量 x=i,y=j; count=1; stuck=0; x+=k; y+=t; //計算該棋向量上有無己方棋 while( x>=0 && y>=0 && x <SIZE && y<SIZE ){ if( board[x][y] == player || board[x][y] == player+2){ count++; x+=k; y+=t; }else if( board[x][y] == opponent || board[x][y] == opponent+2){ stuck++; break; }else break; } //計算己方棋有無被包住 if(count<5){ x=i,y=j; x-=k; y-=t; while( x>=0 && y>=0 && x <SIZE && y<SIZE ){ if( board[x][y] == player || board[x][y] == player+2){ count++; x-=k; y-=t; }else if( board[x][y] == opponent || board[x][y] == opponent+2){ stuck++; break; }else break; } } // 得到value if(stuck==2){ if(count>=5){ value+=50; } } else if(stuck==1){ if(count==3){ value += 3; }if(count==4){ value += 5; }if(count>=5){ value += 100; } }else{ if(count==3){ value +=10; }else if(count==4){ value += 75; }else if(count>=5){ value += 100; } } } } // 對手value else if( board[i][j] == opponent+2 ||board[i][j] == opponent){ for(int q=0; q<4; q++){ k=K[q]; t=T[q]; x=i,y=j; count=1; stuck=0; x+=k; y+=t; while( x>=0 && y>=0 && x <SIZE && y<SIZE ){ if( board[x][y] == opponent || board[x][y] == opponent+2){ count++; x+=k; y+=t; }else if( board[x][y] == player || board[x][y] == player+2){ stuck++; break; }else break; } if(count<5){ x=i,y=j; x-=k; y-=t; while( x>=0 && y>=0 && x <SIZE && y<SIZE ){ if( board[x][y] == opponent || board[x][y] == opponent+2){ count++; x-=k; y-=t; }else if( board[x][y] == player || board[x][y] == player+2){ stuck++; break; }else break; } } if(stuck==2){ if(count==3) value+=5; else if(count==4) value+=5; else if(count>=5) value+=125; } else if(stuck==1){ if(count==3){ value -=0; }if(count==4){ value -=0; }if(count>=5){ value -=125; } } else{ if(count==3){ value -=30; }else if(count==4){ value -= 125; }else if(count==5){ value -= 150; } } } } } } return value; } /* 1.Disc count 2.Valid move count 3.Disc position 4.Game status (win, lose) Try to figure out more features by yourself */
Editor is loading...