#include <iostream>
#include <fstream>
#include <iomanip>
#include <string>
#include <exception>

#include <stdio.h>
#include <io.h>
#include <fcntl.h>

using namespace std;

#define STRATEGY_DEBUG

#include "othello.h"
#include "evaluator.h"
#include "strategy.h"
#include "cirno.h"

#define BOARD_SIZE 6
#define str(x) # x

int main(int argc, char *argv[]){
  Othello othello(BOARD_SIZE);
  
  cout << "Usage: " << argv[0] << " [log_file]" << endl;
  
  Cirno cirno(othello);
  
  //NegaAlphaBetaSearch selector(cirno, 50000, 12);
  AlphaBetaSearch selector(cirno, 500000, 12);
  //NegaMaxSearch selector(cirno, 10000, 12);
  //MinMaxSearch selector(cirno, 30000, 10);
  //Boltzman selector;
  
  if(argc > 1){
    ifstream logfs(argv[1], ios::in);
    logfs >> cirno;
  }
  
  bool man_black(false), man_white(true);
  char c;
  cout << "先手(黒=●)は人間ですか? y / [n] :";
  cin >> c;
  man_black = (c == 'y');
  cout << "後手(白=○)は人間ですか? y / [n] :";
  cin >> c; 
  man_white = (c == 'y');
  
  cout << endl;
  cout << "先手(黒=●) => " << (man_black ? "人間" : "コンピュータ") << endl;
  cout << "後手(白=○) => " << (man_white ? "人間" : "コンピュータ") << endl;
  cout << endl;
  
  while(true){
    cout << othello.current();
    
    if(!othello.current().has_next()){break;}
    
    Othello::State::candidates_t next_states(othello.current().candidates());
    if(next_states.size() > 1){
      if(((othello.current().next() == othello.stone_holder.black())
          ? man_black : man_white)){
        while(true){
          cout << "手を入力してください" << endl;
          int i, j;
          cout << "縦:";
          cin >> i;
          
          while(cin.fail()){
            cin.clear();
            char c;
            cin >> c;
          }
          
          cout << "横:";
          cin >> j;
          
          while(cin.fail()){
            cin.clear();
            char c;
            cin >> c;
          }
          
          try{
            cout << "(縦, 横) = (" << i << ", " << j << ")" << endl;
            othello.mount(i, j);
          }catch(OthelloException e){
            cout << e.what() << endl;
            continue;
          }
          
          break;
        }
      }else{
        cirno.set_evaluate_mode(othello.current());
        selector.select(othello);
      }
    }else{
      cout << "実行可能な手が一つしかないので、自動的にゲームを進めます" << endl;
      Othello::State::candidates_t::key_type v(next_states.begin()->first);
      
      if(v == BOARD_SIZE * BOARD_SIZE){
        cout << "置く場所がないのでスキップ..." << endl;
        othello.order_skip();
      }else{
        int i(v / BOARD_SIZE), j(v % BOARD_SIZE);
        cout << "(縦, 横) = (" << i << ", " << j << ")" << endl;
        othello.mount(i, j);
      }
    }
  }
  
  cout << "ゲーム終了" << endl;
  cout << "黒:" << othello.current().black_stones() << " " 
       << "白:" << othello.current().white_stones() << endl;
  
  return 0;  
}

