コード例 #1
0
ファイル: chessboard.cpp プロジェクト: longsion/ChineseChess
bool ChessBoard::isLegalMove(int mv)
{
    int sqSrc, sqDst, pcSrc, pcDst;
    sqSrc = SRC(mv);
    sqDst = DST(mv);
    if (sqSrc==sqDst)
    {
        return false;
    }
    pcSrc = m_data[sqSrc];
    pcDst = m_data[sqDst];
    if (side(pcSrc)==side(pcDst))
    {
        return false;
    }

    Moves mvs;
    generateMoves(sqSrc, mvs);
    for(int i=0; i<mvs.count(); i++)
    {
        if (mvs[i]==mv)
        {
            return true;
        }
    }
    return false;
}
コード例 #2
0
int UltimateTicTacToeMontecarloAI::expand(int leafIndex, Nodes& nodes, int const player) const
{
  Node& node = nodes[leafIndex];
  node.children.reserve(maxChildren);
  Moves options = movementOptions(node.board, node.previousMove);
  int turn = node.previousMove > 0 ? otherPlayer(node.board.grids.at(node.previousMove)) : player;

  int mostPromisingChildIndex = -1;
  int mostPromisingChildScore = 0;

  while(node.children.size() < maxChildren && !options.empty())
  {
    Move move = options.takeAt(qrand() % options.size());
    int childIndex = nodes.size();
    node.children.append(childIndex);
    Board newBoard(node.board);
    nodes.append( Node {0, 1, playMove(newBoard, move, turn), move, leafIndex, Node::Children()});
    int score = scoreBoard(nodes.last().board, player);
    if(score > mostPromisingChildScore || mostPromisingChildIndex < 0)
    {
      mostPromisingChildIndex = childIndex;
      mostPromisingChildScore = score;
    }
  }

  return mostPromisingChildIndex;
}
コード例 #3
0
UltimateTicTacToeMontecarloAI::Moves UltimateTicTacToeMontecarloAI::movementOptions(Board const& board, int const previousMove) const
{
  int gridIndex = previousMove % GRID_SIZE;
  bool playAny = previousMove < 0 || gridWinner(board.grids, gridIndex) || gridFull(board.grids, gridIndex);

  Moves options;

  if(playAny)
  {
    for(int i = 0; i < BOARD_SIZE; ++i)
    {
      if(board.grids.at(i) == 0)
      {
        options.append(i);
      }
    }
    //qDebug() << "Play to any grid," << options.size() << "options";
  }
  else
  {
    for(int i = 0; i < GRID_SIZE; ++i)
    {
      int position = gridIndex * GRID_SIZE + i;
      if(board.grids.at(position) == 0)
      {
        options.append(position);
      }
    }
    //qDebug() << "Play to grid" << gridIndex << "," << options.size() << "options";
  }

  return options;
}
コード例 #4
0
ファイル: Notation.cpp プロジェクト: ai5/shogi_repeat
/**
*1手前の指し手を取得
*/
const MoveKif*  Notation::getPrevMove() const 
{
	int pos;
	bool ret = false;

	pos = this->number() - (*this->current_moves_)[0].number();
	ASSERT_MSG(pos >= 0, "内部状態が変?");

	MoveKif& move = (*this->current_moves_)[pos];

	pos--;

	Moves* moves = this->current_moves_;

	if (pos < 0 && moves->parent() != nullptr)
	{
		// 親の分岐を取得
		moves = moves->parent();

		pos = move.getParentNumber() - (*moves)[0].number();
	}

	if (pos < 0)
	{
		return nullptr;
	}

	return &(*moves)[pos];
}
コード例 #5
0
ファイル: Board.cpp プロジェクト: Martin1994/pp9k
bool Board::IsCheck(Color side)
{
    Moves* moves = new Moves();
    
    int j = 0;
    for (int i = 0; i < BoardSize * BoardSize; i++)
    {
        if (this->Chesses[i] != NULL && this->Chesses[i]->GetPlayer()->GetSide() == side)
            this->Chesses[i]->GetAvailableMoves(this, moves, true);
        for (; j < moves->GetLength(); j++)
        {
            Move* move = moves->GetMove(j);
            Chess* captured = move->GetChessCaptured();
            if (captured != NULL && captured->GetChessType() == King)
            {
                delete moves;
                
                return true;
            }
        }
    }
    delete moves;
    
    return false;
}
コード例 #6
0
ファイル: chessboard.cpp プロジェクト: longsion/ChineseChess
int ChessBoard::test1_max(int depth, int& mv)
{
    if (depth==0)
    {
        mv = 0;
        return m_vlBlack - m_vlRed;
    }
    Moves mvs;
    //int selfSide = m_sdPlayer;
    int best = -999999;
    generateMoves(mvs);
    for(int i=0; i<mvs.count(); i++)
    {
        int oldVal = m_vlBlack - m_vlRed;
        int pcCapture;
        if (makeMove(mvs[i], pcCapture))
        {
            int temp_mv;
            int val = test1_min(depth-1, temp_mv);
            if (val>best)
            {
               best = val;
               mv = mvs[i];
            }
            undoMakeMove(mvs[i], pcCapture);
        }

        int newVal = m_vlBlack - m_vlRed;
        Q_ASSERT(oldVal==newVal);
    }
    return best;
}
コード例 #7
0
ファイル: MoveGenerator.cpp プロジェクト: hknexgen/morris
Moves MoveGenerator::generateOpening(const Board& board) const
{
	Moves result;
	if(board.getIdleCount() == 0)
	{
		QMessageBox::critical(0, "error", "idle == 0");
		return result;
	}
	for(int i=0; i<23; ++i)
	{
		if(board.isEmpty(i))
		{
			Board next = board.makeChild();  // a clone
			next.setManAt(i, board.getSelfColor());
			if(next.closeMill(i))
			{
				Moves removeMoves = generateRemove(next, board.getOpponentColor());  // remove 1 opponent chessman
				copy(removeMoves.begin(), removeMoves.end(), back_inserter(result));
			}
			else
				result.push_back(next);
		}
	}
	return result;
}
コード例 #8
0
ファイル: chessboard.cpp プロジェクト: longsion/ChineseChess
void ChessBoard::generatePawnMoves(ChessBoard& board, int sqSrc, Moves& mvs)
{
    int sqDst;

    if (board.m_sdPlayer != SQ_SIDE(sqSrc))
    {
        sqDst = sqSrc - 1;
        if (IN_BOARD(sqDst) && board.canMove(board, sqSrc, sqDst))
        {
            mvs.append(ChessBoard::mv(sqSrc, sqDst));
        }
        sqDst = sqSrc + 1;
        if (IN_BOARD(sqDst) && board.canMove(board, sqSrc, sqDst))
        {
            mvs.append(ChessBoard::mv(sqSrc, sqDst));
        }
    }


    if (board.m_sdPlayer==0)
    {
        sqDst = sqSrc - 16;
    }
    else{
        sqDst = sqSrc + 16;
    }
    if (IN_BOARD(sqDst) && board.canMove(board, sqSrc, sqDst))
    {
        mvs.append(ChessBoard::mv(sqSrc, sqDst));
    }
}
コード例 #9
0
const ConnectThree::Move ConnectThree::CheckTwoOther(const std::bitset<3>& is_player_human) const
{
  const Moves moves(GetAllPossibleMoves());

  const int nMoves = moves.size();
  if (nMoves==0) return CreateInvalidMove();
  {
    //Get anti-human moves
    Moves v;
    BOOST_FOREACH(const Move& m, moves)
    {
      assert(CanDoMove(m));
      //Player is human
      if (is_player_human[boost::tuples::get<2>(m)])
        v.push_back(m);
    }
    //If there are anti-player moves, choose one at random
    if (!v.empty())
    {
      const Move m = v[std::rand() % v.size()];
      assert(CanDoMove(m));
      return
        boost::tuples::make_tuple(
          boost::tuples::get<0>(m),
          boost::tuples::get<1>(m),
          boost::tuples::get<2>(m));
    }
  }
コード例 #10
0
ファイル: Move.cpp プロジェクト: ai5/shogi_repeat
/*-----------------------------------------------------------------------------*/
void MoveKif::AddBranch(Moves* parent, const Moves& moves)
{
	this->branches_.emplace_back(new Moves(moves));
	
	Moves* m = this->branches_.back().get();
	m->set_parent(parent);
}
コード例 #11
0
Moves BoardC4::get_possible_moves(Token player) const {
	Moves moves;

	for (Size column=0; column<width; column++) {
		if (tokens[column]<=token_for_columns[column]) moves.push_back(new MoveC4(player,column));
	}

	return moves;
}
コード例 #12
0
void Shogi::GenerateMoves1Step( Moves& moves, GEN_INFO& info, int dir ){
/************************************************
任意の方向への着手可能手を列挙する。
************************************************/
	int from; // 移動元
	int to; // 移動先
	int n;
	int flag;
	bool nz;

	if( info.dir_p != 0 && dir != info.dir_p && dir != -info.dir_p )
		return;

	from = info.addr;
	to = info.addr + dir;
	if( ban[to] == EMPTY || ban[to] & (ksengo^SENGO) ){
		if(    ( info.flag & MOVE_CAPTURE   && ban[to] != EMPTY )
			|| ( info.flag & MOVE_NOCAPTURE && ban[to] == EMPTY )
			// 新しいGenerateCheckOnBoard内で空き王手のチェックは行う。
			/*|| ( info.flag & MOVE_CHECK && IsDiscCheckMove( info.ou2, to, from ) )*/
		){
			flag = 1;
		}
		else{
			flag = 0;
		}

		// 着手可能手追加
		n = 0;
		if( !( info.koma & NARI ) && info.koma != SKI && info.koma != GKI &&
			( ( ksengo == SENTE && ( to <= BanAddr(9,3) || from <= BanAddr(9,3) ) ) ||
			  ( ksengo == GOTE  && ( to >= BanAddr(1,7) || from >= BanAddr(1,7) ) ) ) )
		{
			// 成る場合
			if( flag || info.flag & MOVE_PROMOTE ||
				( info.flag & MOVE_CHECK && IsCheckMove( info.ou2, to, info.koma + NARI ) ) ||
				( info.flag & MOVE_NCHECK && !IsCheckMove( info.ou2, to, info.koma + NARI ) )
			){
				moves.Add( from, to, 1, info.koma );
			}
			n = 1;
		}
		nz = !n || Narazu( info.koma, to );
		if( !MoveError( info.koma, to ) &&
			// 王手の場合でも不成は生成しないように変更
			( /*info.flag & MOVE_CHECK ||*/ nz ) )
		{
			// 成らない場合
			if( flag || info.flag & MOVE_NOPROMOTE ||
				( info.flag & MOVE_CHECK && IsCheckMove( info.ou2, to, info.koma ) ) ||
				( nz && info.flag & MOVE_NCHECK && !IsCheckMove( info.ou2, to, info.koma ) )
			){
				moves.Add( from, to, 0, info.koma );
			}
		}
	}
}
コード例 #13
0
ファイル: Move.cpp プロジェクト: ai5/shogi_repeat
/*-----------------------------------------------------------------------------*/
void MoveKif::AddBranch(Moves* parent, const MoveKif& move)
{
	this->branches_.emplace_back(new Moves());

	Moves* moves = this->branches_.back().get();

	moves->set_parent(parent);
	moves->push_back(move);
}
コード例 #14
0
void ConsoleManager::showMoves() const {
  Moves moves;
  MoveGenerator::generate(record_.getBoard(), moves);
  for (auto ite = moves.begin(); ite != moves.end(); ite++) {
    if (record_.getBoard().isValidMoveStrict(*ite)) {
      std::cout << ite->toString() << ' ';
    }
  }
  std::cout << std::endl;
}
コード例 #15
0
ファイル: Board.cpp プロジェクト: Martin1994/pp9k
bool Board::HasMove(Color side)
{
    Moves* moves = this->GetAllAvailableMoves(side);
    
    bool has_move = moves->GetLength() > 0;
    
    delete moves;
    
    return has_move;
}
コード例 #16
0
void build_path(ull_t v, const Searched & searched, Moves & steps) {
  Searched::const_iterator it = searched.find(v);
  while (it != searched.end()) {
    const State & s = it->second;
    steps.push_back(s.step);
    it = searched.find(s.parent);
  }
  //pop up the first step, which must be 0, rather than one of U,D,L,R
  steps.pop_back();
  reverse(steps.begin(), steps.end());
}
コード例 #17
0
ファイル: Move.cpp プロジェクト: ai5/shogi_repeat
/*-----------------------------------------------------------------------------*/
Moves* MoveKif::MakeBranch(Moves* parent)
{
	this->branches_.emplace_back(new Moves());

	this->current_ = this->branches_.size() - 1; // カレント変えとく

	Moves* moves = this->branches_.back().get();
	moves->set_parent(parent);

	return moves;
}
コード例 #18
0
ファイル: move.cpp プロジェクト: axem/spritepack
	Move bestMove(const Moves& moves)
	{
		if (!moves.empty())
		{
			return *min_element(moves.begin(), moves.end());
		} 
		else 
		{
			return Move(Cost::infinity());
		}
	}
コード例 #19
0
TEST(MoveGeneratorTest, testDrop) {
  {
    // 先手の手
    std::string src =
"P1+TO-KE *  *  *  *  *  *  * \n"
"P2 *  *  *  *  *  *  *  *  * \n"
"P3 *  *  * -OU *  *  * -FU * \n"
"P4 *  *  *  *  *  *  *  *  * \n"
"P5 *  *  * +FU * -KI *  *  * \n"
"P6 *  *  *  *  *  *  *  *  * \n"
"P7 *  * +FU *  *  *  * +FU * \n"
"P8 *  * +OU *  *  *  *  *  * \n"
"P9 *  *  *  * -KY * -RY *  * \n"
"P+00FU00FU00KY00KE00KA\n"
"P-\n"
"+\n";
    std::istringstream iss(src);
    Board board;
    CsaReader::readBoard(iss, board);

    // FUx45 KYx63 KEx54 KAx70
    Moves moves;
    MoveGenerator::generateDrop(board, moves);
    ASSERT_EQ(45+63+54+70, moves.size());
  }

  {
    // 後手の手
    std::string src =
"P1 *  *  *  * +KY * +RY *  * \n"
"P2 *  * -OU *  *  *  *  *  * \n"
"P3 *  * -FU *  *  *  * -FU * \n"
"P4 *  *  *  *  *  *  *  *  * \n"
"P5 *  *  * -FU * +KI *  *  * \n"
"P6 *  *  *  *  *  *  *  *  * \n"
"P7 *  *  * +OU *  *  * +FU * \n"
"P8 *  *  *  *  *  *  *  *  * \n"
"P9-TO+KE *  *  *  *  *  *  * \n"
"P+\n"
"P-00FU00FU00KY00KE00KA\n"
"-\n";
    std::istringstream iss(src);
    Board board;
    CsaReader::readBoard(iss, board);

    // FUx45 KYx63 KEx54 KAx70
    Moves moves;
    MoveGenerator::generateDrop(board, moves);
    ASSERT_EQ(45+63+54+70, moves.size());
  }
}
コード例 #20
0
int Book::GetMoveAll( Shogi* pshogi, Moves& moves, TYPE type ){
/************************************************
定跡手を列挙する。
************************************************/
	int i;
	int flag;
	list<BLIST>::iterator ib;
	list<MLIST>::iterator im;
	list<MLIST>* pmlist;
	uint64 hash = pshogi->GetHash();
	MOVE mtemp;

	i = (int)( hash & BOOK_HASH_MASK );

	// 局面が既にあるか調べる。
	flag = 0;
	for( ib = blist[i].begin() ; ib != blist[i].end() ; ++ib ){
		if( (*ib).hash == hash ){
			flag = 1;
			break;
		}
	}

	if( flag == 0 )
		return 0;

	// 指し手を列挙
	pmlist = &(*ib).mlist;
	for( im = pmlist->begin() ; im != pmlist->end() ; ++im ){
		mtemp.Import( (*im).mv );
		if( pshogi->IsLegalMove( mtemp ) ){
			switch( type ){
			// 評価値を用いる場合
			case TYPE_EVAL:
				mtemp.value = (*im).val;
				break;
			// 出現頻度を用いる場合
			case TYPE_FREQ:
			default:
				mtemp.value = (*im).cnt * 100 / (*ib).cnt;
				break;
			}
			moves.Add( mtemp );
		}
	}
	moves.Sort();

	return moves.GetNumber();
}
コード例 #21
0
 Moves valid_moves() const {
   int i = space_index();
   int row = i / 4;
   int col = i % 4;
   Moves cand;
   if (row != 0)
     cand.push_back('U');
   if (row != 3)
     cand.push_back('D');
   if (col != 0)
     cand.push_back('L');
   if (col != 3)
     cand.push_back('R');
   return cand;
 }
コード例 #22
0
TEST(MoveGeneratorTest, testNoCap) {
  {
    std::string src =
"P1-KY-KE-GI-KI * -KI * -KE-KY\n"
"P2 * -OU *  *  *  *  * -HI * \n"
"P3-FU-FU-FU-FU-FU * -KA * -FU\n"
"P4 *  *  *  * -GI-FU-FU+KA * \n"
"P5 *  *  *  *  *  *  *  *  * \n"
"P6+FU * +FU * +FU *  *  *  * \n"
"P7 * +FU+GI+FU * +FU+FU * +FU\n"
"P8 *  * +OU * +KI *  * +HI * \n"
"P9+KY+KE * +KI *  * +GI+KE+KY\n"
"P+00FU\n"
"P-00FU\n"
"+\n";
    std::istringstream iss(src);
    Board board;
    CsaReader::readBoard(iss, board);

    Moves moves;
    MoveGenerator::generateNoCap(board, moves);
    ASSERT_EQ(40, moves.size());
  }

  {
    // 先手の駒 銀から飛車まで
    std::string src =
"P1 *  *  *  * -OU+KA *  *  * \n"
"P2+KI *  *  *  *  *  * +HI * \n"
"P3 *  * +GI *  *  *  *  *  * \n"
"P4+GI *  *  *  *  *  *  *  * \n"
"P5 *  * +KA *  *  *  *  *  * \n"
"P6 *  *  *  *  *  * +HI *  * \n"
"P7 *  *  *  *  *  *  *  *  * \n"
"P8 *  *  *  *  *  *  *  *  * \n"
"P9 *  *  *  * +OU * -TO *  * \n"
"P+\n"
"P-\n"
"+\n";
    std::istringstream iss(src);
    Board board;
    CsaReader::readBoard(iss, board);

    Moves moves;
    MoveGenerator::generateNoCap(board, moves);
    ASSERT_EQ(43, moves.size());
  }
}
コード例 #23
0
ファイル: Board.cpp プロジェクト: Martin1994/pp9k
bool Board::IsCheckmate(Color side)
{
    if (!this->IsCheck(side))
    {
        return false;
    }
    
    Color opponent = side == White ? Black : White;
    Moves* moves = this->GetAllAvailableMoves(opponent);
    
    bool checkmate = moves->GetLength() == 0;
    
    delete moves;
    
    return checkmate;
}
コード例 #24
0
void Shogi::GenerateMovesDropKy( Moves& moves ){
/************************************************
香車を打つ手を列挙する。
************************************************/
	KOMA koma;
	int to;
	int i, j;

	koma = KY | ksengo;

	if( dai[koma] == 0 )
		return;

	for( j = 0x10 ; j <= 0x90 ; j += 0x10 ){
		for( i = 1 ; i <= 9 ; i++ ){
			to = i + j;
			if( ban[to] == EMPTY ){
				// 合法手チェック
				if( ksengo == SENTE ){
					if( to <= BanAddr(9,1) )
						continue;
				}
				else{
					if( to >= BanAddr(1,9) )
						continue;
				}

				// 着手可能手追加
				moves.Add( DAI + koma, to, 0, koma );
			}
		}
	}
}
コード例 #25
0
void Shogi::GenerateTacticalMoves( Moves& moves ){
/************************************************
戦略的な手を列挙する。
Capture, Promote, (King)
************************************************/
	GEN_INFO info;

	// 生成する指し手の種類
	SetGenInfo( info, MOVE_CAPTURE | MOVE_PROMOTE );

	// ピン
	SetGenInfoPin( info );

	if( !info.check ){
		// 盤上
		GenerateMovesOnBoard( moves, info );
	}
	else if( info.check != DOUBLE_CHECK ){
		GenerateCapEvasion( moves, info );
		GenerateNoCapEvasion( moves, info );
	}

	if( moves.GetNumber() == 0 ){
		// 玉を動かす手
		info.flag |= MOVE_KING;
		GenerateMovesOu( moves, info );
	}
}
コード例 #26
0
ファイル: PlayerAI1.cpp プロジェクト: Martin1994/pp9k
void PlayerAI1::RequestMove()
{
    Moves* moves = this->Game->CurrentBoard->GetAllAvailableMoves(this->Side);

    srand (time(NULL));
    int index = rand() % moves->GetLength();

    Move* move = moves->GetMove(index);
    Chess* before = move->GetChessBeforeMove();
    Chess* after = move->GetChessAfterMove();

    this->Game->MakeMove(before->GetX(), before->GetY(), after->GetX(), after->GetY(), after->GetChessType());

    delete moves;

    CheckDraw();
}
コード例 #27
0
ファイル: Notation.cpp プロジェクト: ai5/shogi_repeat
/*-----------------------------------------------------------------------------*/
void Notation::AddBranch(const Moves& src_moves)
{
	Moves* dest_moves = this->current_moves_; // 一旦カレントで作成
	MoveKif* dest_move = this->move_current_;


	const MoveKif& last_move = dest_moves->back();

	if (&last_move == dest_move)
	{
		// 追加先が末尾の場合
		dest_moves->insert(dest_moves->end(), src_moves.begin(), src_moves.end());
	}
	else
	{
		// 追加先が途中の場合
		dest_move->AddBranch(dest_moves, src_moves);
	}
}
コード例 #28
0
ファイル: MoveGenerator.cpp プロジェクト: hknexgen/morris
Moves MoveGenerator::generateRemove(const Board& old, QChar color) const
{
	Moves result;
	for(int i=0; i<23; ++i)
	{
		if(old.getManAt(i) == color)
		{
			if(!old.closeMill(i))
			{
				// DO NOT use old.makeChild
				// next is a semi-finished product of a move
				Board next = old;
				next.setManAt(i, 'x');
				result.push_back(next);
			}
		}
	}
	if(result.empty())      // no possible remove
		result.push_back(old);
	return result;
}
コード例 #29
0
ファイル: Notation.cpp プロジェクト: ai5/shogi_repeat
/*-----------------------------------------------------------------------------*/
void Notation::DeleteBranch(int no)
{
	MoveKif* move = this->move_current_; // 一旦カレントに対する操作にしておく
	Moves* moves = this->current_moves_;
	int num = this->number();

	if (no == -1)
	{
		int pos = num - (*moves)[0].number();

		// 次の要素から最後までを削除
		moves->erase(moves->begin() + pos + 1, moves->end());

		if (move->branches().size() != 0)
		{
			// ブランチをずらす
			moves->insert(moves->end(), move->branches()[0]->begin(), move->branches()[0]->end());

			move->DeleteBranch(0);
		}
	}
	else
	{
		move->DeleteBranch(no);
	}
}
コード例 #30
0
ファイル: chessboard.cpp プロジェクト: longsion/ChineseChess
bool ChessBoard::IsMate()
{   
    //qDebug()<<"check isMate side="<<m_sdPlayer;
    //int selfSide = m_sdPlayer;
    Moves mvs;
    generateMoves(mvs);
    for(int i=0; i<mvs.count(); i++)
    {
        //qDebug()<<"尝试解招:"<< mvString(mvs[i]);
        int pcCaptured = _movePiece(mvs[i]);
        if (!isChecked())
        {
            _undoMovePiece(mvs[i], pcCaptured);
            //qDebug()<<"!!!解招:"<< mvString(mvs[i]);
            return false;
        }
        else{
            _undoMovePiece(mvs[i], pcCaptured);
        }
    }
    return true;
}