Example #1
0
void CopyMove(struct Move* moveDst,struct Move* moveSrc){
	CopyBoard(moveDst->board_after_move, moveSrc->board_after_move);
	moveDst->dst = moveSrc->dst;
	moveDst->src = moveSrc->src;
	moveDst->prev = moveSrc->prev;
	moveDst->next = moveSrc->next;
	moveDst->promotion = moveSrc->promotion;
}
Example #2
0
File: game.c Project: zhu-jz/turtle
void ClearGame(GAME *Game, const BOARD *StartBoard) {

   if (StartBoard == NULL) {
      ClearBoard(Game->StartBoard);
   } else {
      CopyBoard(StartBoard,Game->StartBoard);
   }

   CopyBoard(Game->StartBoard,Game->Board);

   Game->MoveNo       = 0;
   Game->Move[0].Move = NO_MOVE;

   ElapsedTime[0] = 0.0;
   ElapsedTime[1] = 0.0;

   TurnBegin = CurrentTime();
}
Example #3
0
File: game.c Project: zhu-jz/turtle
void GotoGameMove(GAME *Game, int MoveNo) {

   CopyBoard(Game->StartBoard,Game->Board);
   if (RestoreClocks) ElapsedTime[0] = ElapsedTime[1] = 0.0;

   for (Game->MoveNo = 0; Game->MoveNo < MoveNo && Game->Move[Game->MoveNo].Move != NO_MOVE; Game->MoveNo++) {
      if (RestoreClocks) ElapsedTime[Game->Board->Colour>0] += Game->Move[Game->MoveNo].Time;
      DoMove(Game->Board,Game->Move[Game->MoveNo].Move);
   }

   TurnBegin = CurrentTime();
}
// Leaf expansion.
// ============================= Expansion Related ==================================
static BOOL send_to_cnn(ThreadInfo *info, TreeBlock *b, const Board *board) {
  // Send the current player to CNN for evaluation.
  // Check if someone else has sent it.
  TreeHandle *s = info->s;
  info->cnn_send_infunc ++;

  // If BIT_CNN_TRY_SEND has been set to 1, then someone else is sending the board, then we return.
  if (cnn_data_fetch_set_evaluated_bit(&b->cnn_data, BIT_CNN_TRY_SEND)) return FALSE;

  // Otherwise we got the token and send.
  if (b->cnn_data.seq == s->seq && cnn_data_get_evaluated_bit(&b->cnn_data, BIT_CNN_SENT)) {
    PRINT_DEBUG("b = %lx (%u) is already sent to the server, do not send again!\n", (uint64_t)b, ID(b));
    cnn_data_clear_evaluated_bit(&b->cnn_data, BIT_CNN_TRY_SEND);
    return FALSE;
  }

  // If the sequence number is out-of-date, we just clear it.
  if (b->cnn_data.seq != s->seq) cnn_data_clear_evaluated_bit(&b->cnn_data, BIT_CNN_SENT);

  // Send the message.
  MBoard mboard;
  mboard.b = (uint64_t) b;
  mboard.seq = s->seq;
  CopyBoard(&mboard.board, board);

/*  ShowBoard(&mboard.board, SHOW_LAST_MOVE);
  if (info->cnn_send_infunc == 2) {
    exit(0);
  }
*/
  info->cnn_send_attempt ++;

  b->cnn_data.seq = s->seq;
  cnn_data_set_evaluated_bit(&b->cnn_data, BIT_CNN_SENT);

  if (s->callbacks.callback_send_board(s->callbacks.context, info->ex_id, &mboard)) {
    // Note that in asynchronized version, Ideally, setting BIT_CNN_SENT and ExLocalClientSendBoard should be in the critical region.
    // Otherwise the board might get sent twice. But it should not harm too much.
    // Save the sent sequence.
    info->cnn_send_success ++;
    // Clear the evaluation TRY_SEND bit so that other people can enter the critical session.
    cnn_data_clear_evaluated_bit(&b->cnn_data, BIT_CNN_TRY_SEND);
    return TRUE;
  } else {
    cnn_data_clear_evaluated_bit(&b->cnn_data, BIT_CNN_SENT);
    // Release the token so that other thread can resend.
    cnn_data_clear_evaluated_bit(&b->cnn_data, BIT_CNN_TRY_SEND);
    return FALSE;
  }
}
Example #5
0
struct Move* createMove(int x, int y, int i, int j, char some_board[BOARD_SIZE][BOARD_SIZE], char promotion){
	struct Move* newMove = calloc(1,sizeof(struct Move));
	moveLeaks++;
	newMove->dst.x = i;
	newMove->dst.y = j;
	newMove->src.x = x;
	newMove->src.y = y;

	CopyBoard(newMove->board_after_move, some_board);
	newMove->board_after_move[i][j] = newMove->board_after_move[x][y];
	newMove->board_after_move[x][y] = EMPTY;
	newMove->next = NULL;
	newMove->prev = NULL;
	if (promotion != NULL){
		newMove->board_after_move[i][j] = promotion;
	}
	return newMove;
}
// Fast rollout default policy.
// For now we will just omit Region *r and max_depth, and simulate until the end of game.
DefPolicyMove fast_rollout_def_policy(void *def_policy, void *context, RandFunc rand_func, Board* board, const Region *r, int max_depth, BOOL verbose) {
  if (verbose) printf("Init fast rollout def policy!\n");

  void *be = PatternV2InitBoardExtra(def_policy, board);
  SampleSummary summary;

  if (verbose) printf("Start sampling.\n");
  PatternV2SampleUntil(be, context, rand_func, NULL, &summary);

  if (verbose) printf("Copying final board back.\n");
  CopyBoard(board, PatternV2GetBoard(be));

  if (verbose) printf("Clean up.\n");
  PatternV2DestroyBoardExtra(be);

  // Return the last move.
  DefPolicyMove move = { .m = board->_last_move, .gamma = 0, .type = NORMAL, .game_ended = IsGameEnd(board) };
  return move;
}
Example #7
0
char *GetCaptureText(enum ChessPiece board[8][8], char *longmove)
{
	char *letters = "abcdefgh";
	char *numbers = "87654321";
	char *pieces = "oPNBRQKpnbrqk";
	char *submove;
	char txt[512];
	enum ChessPiece tempboard[8][8];

	txt[0] = '\0';
	submove = strdup(longmove);

	/* filter for castling */
	if (strlen(longmove) == 9 && longmove[4] == ' ')
	{
		int x1, y1, x2, y2;

		x1 = (int)(strchr(letters, longmove[0]) - letters);
		y1 = (int)(strchr(numbers, longmove[1]) - numbers);

		x2 = (int)(strchr(letters, longmove[5]) - letters);
		y2 = (int)(strchr(numbers, longmove[6]) - numbers);

		if ((board[x1][y1] == CP_WKING && board[x2][y2] == CP_WROOK)
		 || (board[x1][y1] == CP_WROOK && board[x2][y2] == CP_WKING) 
		 || (board[x1][y1] == CP_BKING && board[x2][y2] == CP_BROOK) 
		 || (board[x1][y1] == CP_WROOK && board[x2][y2] == CP_WKING))
		{
			return "";
		}
	}

	CopyBoard(board, tempboard);

	do {
		char *space = strchr(submove, ' ');
		int x, y, len;
		enum ChessPiece captured;
		
		if (space)
		{
			len = space - submove;
			*space = '\0';
		}
		else
		{
			len = strlen(submove);
		}

		if (len == 3)
		{
			x = (int)(strchr(letters, submove[0]) - letters);
			y = (int)(strchr(numbers, submove[1]) - numbers);
		}
		else
		{
			x = (int)(strchr(letters, submove[2]) - letters);
			y = (int)(strchr(numbers, submove[3]) - numbers);
		}

		captured = tempboard[x][y];

		if (tempboard[x][y] != CP_NONE)
		{
			strncat(txt, &(pieces[captured]), 1);
			strncat(txt, &(letters[x]), 1);
			strncat(txt, &(numbers[y]), 1);
		}

		ExecuteMove(tempboard, submove, 0, NULL, NULL);

		if (space)
		{
			submove = space + 1;
		}
		else
		{
			submove = NULL;
		}

	} while (submove && *submove);

	return strdup(txt);
}
Example #8
0
int IsMoveLegal(enum ChessPiece board[8][8], int oldx, int oldy, int newx, int newy, enum ChessCastling *castling, char **enpassanttarget)
{
	enum ChessPiece tempboard[8][8];
	char *letters = "abcdefgh";
	char *numbers = "87654321";
	char move[5];
	int iswhitemove = IsPieceWhite(board[oldx][oldy]);

	if (CanPieceMoveHere(board, oldx, oldy, newx, newy, castling, enpassanttarget))
	{
		/* is this a castling move?  Then check the intermediate square */
		if (oldx == 4 && oldy == 7 && newy == 7 && (newx == 6 || newx == 2) && board[oldx][oldy] == CP_WKING)
		{
			CopyBoard(board, tempboard);

			if (newx == 6)
			{
				strcpy(move, "e8f8");
				ExecuteMove(tempboard, move, 0, NULL, NULL);
				if (!IsPositionLegal(tempboard, !iswhitemove))
				{
					return 0;
				}
			}

			if (newx == 2)
			{
				strcpy(move, "e8d8");
				ExecuteMove(tempboard, move, 0, NULL, NULL);
				if (!IsPositionLegal(tempboard, !iswhitemove))
				{
					return 0;
				}
			}
		}

		if (oldx == 4 && oldy == 7 && newy == 0 && (newx == 6 || newx == 2) && board[oldx][oldy] == CP_BKING)
		{
			CopyBoard(board, tempboard);

			if (newx == 6)
			{
				strcpy(move, "e1f1");
				ExecuteMove(tempboard, move, 0, NULL, NULL);
				if (!IsPositionLegal(tempboard, !iswhitemove))
				{
					return 0;
				}
			}

			if (newx == 2)
			{
				strcpy(move, "e1d1");
				ExecuteMove(tempboard, move, 0, NULL, NULL);
				if (!IsPositionLegal(tempboard, !iswhitemove))
				{
					return 0;
				}
			}
		}

		CopyBoard(board, tempboard);
		move[0] = letters[oldx];
		move[1] = numbers[oldy];
		move[2] = letters[newx];
		move[3] = numbers[newy];
		move[4] = '\0';

		ExecuteMove(tempboard, move, 0, NULL, NULL);
		return IsPositionLegal(tempboard, !iswhitemove);
	}

	return 0;
}
Example #9
0
/* Build the list of games in the open file f.
 * Returns 0 for success or error number.
 */
int
GameListBuild (FILE *f)
{
    ChessMove cm, lastStart;
    int gameNumber;
    ListGame *currentListGame = NULL;
    int error, scratch=100, plyNr=0, fromX, fromY, toX, toY;
    int offset;
    char lastComment[MSG_SIZ], buf[MSG_SIZ];
    TimeMark t, t2;

    GetTimeMark(&t);
    GameListFree(&gameList);
    yynewfile(f);
    gameNumber = 0;
    movePtr = 0;

    lastStart = (ChessMove) 0;
    yyskipmoves = FALSE;
    do {
        yyboardindex = scratch;
	offset = yyoffset();
	quickFlag = plyNr + 1;
	cm = (ChessMove) Myylex();
	switch (cm) {
	  case GNUChessGame:
	    if ((error = GameListNewGame(&currentListGame))) {
		rewind(f);
		yyskipmoves = FALSE;
		return(error);
	    }
	    currentListGame->number = ++gameNumber;
	    currentListGame->offset = offset;
	    if(1) { CopyBoard(boards[scratch], initialPosition); plyNr = 0; currentListGame->moves = PackGame(boards[scratch]); }
	    if (currentListGame->gameInfo.event != NULL) {
		free(currentListGame->gameInfo.event);
	    }
	    currentListGame->gameInfo.event = StrSave(yy_text);
	    lastStart = cm;
	    break;
	  case XBoardGame:
	    lastStart = cm;
	    break;
	  case MoveNumberOne:
	    switch (lastStart) {
	      case GNUChessGame:
		break;		/*  ignore  */
	      case PGNTag:
		lastStart = cm;
		break;		/*  Already started */
	      case (ChessMove) 0:
	      case MoveNumberOne:
	      case XBoardGame:
		if ((error = GameListNewGame(&currentListGame))) {
		    rewind(f);
		    yyskipmoves = FALSE;
		    return(error);
		}
		currentListGame->number = ++gameNumber;
		currentListGame->offset = offset;
		if(1) { CopyBoard(boards[scratch], initialPosition); plyNr = 0; currentListGame->moves = PackGame(boards[scratch]); }
		lastStart = cm;
		break;
	      default:
		break;		/*  impossible  */
	    }
	    break;
	  case PGNTag:
	    lastStart = cm;
	    if ((error = GameListNewGame(&currentListGame))) {
		rewind(f);
		yyskipmoves = FALSE;
		return(error);
	    }
	    currentListGame->number = ++gameNumber;
	    currentListGame->offset = offset;
	    ParsePGNTag(yy_text, &currentListGame->gameInfo);
	    do {
		yyboardindex = 1;
		offset = yyoffset();
		cm = (ChessMove) Myylex();
		if (cm == PGNTag) {
		    ParsePGNTag(yy_text, &currentListGame->gameInfo);
		}
	    } while (cm == PGNTag || cm == Comment);
	    if(1) {
		int btm=0;
		if(currentListGame->gameInfo.fen) ParseFEN(boards[scratch], &btm, currentListGame->gameInfo.fen, FALSE);
		else CopyBoard(boards[scratch], initialPosition);
		plyNr = (btm != 0);
		currentListGame->moves = PackGame(boards[scratch]);
	    }
	    if(cm != NormalMove) break;
	  case IllegalMove:
		if(appData.testLegality) break;
	  case NormalMove:
	    /* Allow the first game to start with an unnumbered move */
	    yyskipmoves = FALSE;
	    if (lastStart == (ChessMove) 0) {
	      if ((error = GameListNewGame(&currentListGame))) {
		rewind(f);
		yyskipmoves = FALSE;
		return(error);
	      }
	      currentListGame->number = ++gameNumber;
	      currentListGame->offset = offset;
	      if(1) { CopyBoard(boards[scratch], initialPosition); plyNr = 0; currentListGame->moves = PackGame(boards[scratch]); }
	      lastStart = MoveNumberOne;
	    }
	  case WhiteCapturesEnPassant:
	  case BlackCapturesEnPassant:
	  case WhitePromotion:
	  case BlackPromotion:
	  case WhiteNonPromotion:
	  case BlackNonPromotion:
	  case WhiteKingSideCastle:
	  case WhiteQueenSideCastle:
	  case BlackKingSideCastle:
	  case BlackQueenSideCastle:
	  case WhiteKingSideCastleWild:
	  case WhiteQueenSideCastleWild:
	  case BlackKingSideCastleWild:
	  case BlackQueenSideCastleWild:
	  case WhiteHSideCastleFR:
	  case WhiteASideCastleFR:
	  case BlackHSideCastleFR:
	  case BlackASideCastleFR:
		fromX = currentMoveString[0] - AAA;
		fromY = currentMoveString[1] - ONE;
		toX = currentMoveString[2] - AAA;
		toY = currentMoveString[3] - ONE;
		plyNr++;
		ApplyMove(fromX, fromY, toX, toY, currentMoveString[4], boards[scratch]);
		if(currentListGame && currentListGame->moves) PackMove(fromX, fromY, toX, toY, boards[scratch][toY][toX]);
	    break;
        case WhiteWins: // [HGM] rescom: save last comment as result details
        case BlackWins:
        case GameIsDrawn:
        case GameUnfinished:
	    if(!currentListGame) break;
	    if(currentListGame->gameInfo.result == GameUnfinished)
		currentListGame->gameInfo.result = cm; // correct result tag with actual result
	    if (currentListGame->gameInfo.resultDetails != NULL) {
		free(currentListGame->gameInfo.resultDetails);
	    }
	    if(yy_text[0] == '{') {
		char *p;
		safeStrCpy(lastComment, yy_text+1, sizeof(lastComment)/sizeof(lastComment[0]));
		if((p = strchr(lastComment, '}'))) *p = 0;
		currentListGame->gameInfo.resultDetails = StrSave(lastComment);
	    }
	    break;
	  default:
	    break;
	}
	if(gameNumber % 1000 == 0) {
	    snprintf(buf, MSG_SIZ, _("Reading game file (%d)"), gameNumber);
	    DisplayTitle(buf); DoEvents();
	}
    }
    while (cm != (ChessMove) 0);

 if(currentListGame) {
    if(!currentListGame->moves) DisplayError("Game cache overflowed\nPosition-searching might not work properly", 0);

    if (appData.debugMode) {
	for (currentListGame = (ListGame *) gameList.head;
	     currentListGame->node.succ;
	     currentListGame = (ListGame *) currentListGame->node.succ) {

	    fprintf(debugFP, "Parsed game number %d, offset %ld:\n",
		    currentListGame->number, currentListGame->offset);
	    PrintPGNTags(debugFP, &currentListGame->gameInfo);
	}
    }
  }
    if(appData.debugMode) { GetTimeMark(&t2);printf("GameListBuild %ld msec\n", SubtractTimeMarks(&t2,&t)); }
    quickFlag = 0;
    PackGame(boards[scratch]); // for appending end-of-game marker.
    DisplayTitle("WinBoard");
    rewind(f);
    yyskipmoves = FALSE;
    return 0;
}
Example #10
0
static bool
middle_ladder_walk(Board *b, Board *bset, group_t laddered, Coord nextmove, Stone lcolor)
{
	assert(group_at(b, laddered)->liberties == 1);

	/* First, escape. */
  /*
	if (DEBUGL(6))
		fprintf(stderr, "  ladder escape %s\n", coord2sstr(nextmove, b));
  */
  GroupId4 ids;
  if (!TryPlay2(b, nextmove, &ids)) error("The play should never be wrong!");
  Play(b, &ids);

	// laddered = group_at(b, laddered);
  /*
	if (DEBUGL(8)) {
		board_print(b, stderr);
		fprintf(stderr, "%s c %d\n", coord2sstr(laddered, b), board_group_info(b, laddered).libs);
	}
  */

  int laddered_libs = b->_groups[laddered].liberties;

	if (laddered_libs == 1) {
    /*
		if (DEBUGL(6))
			fprintf(stderr, "* we can capture now\n");
    */
		return true;
	}
	if (laddered_libs > 2) {
    /*
		if (DEBUGL(6))
			fprintf(stderr, "* we are free now\n");
    */
		return false;
	}

  FOR4(nextmove, _, c) {
		if (board_at(b, c) == OPPONENT(lcolor) && group_at(b, c)->liberties == 1) {
			/* We can capture one of the ladder stones
			 * anytime later. */
			/* XXX: If we were very lucky, capturing
			 * this stone will not help us escape.
			 * That should be pretty rate. */
      /*
			if (DEBUGL(6))
				fprintf(stderr, "* can capture chaser\n");
      */
			return false;
		}
	} ENDFOR4

	/* Now, consider alternatives. */
	int liblist[2], libs = 0;
  Coord tmp_libs[2];
  get_nlibs_of_group(b, laddered, 2, tmp_libs);
	for (int i = 0; i < 2; i++) {
		Coord ataristone = tmp_libs[i];
		Coord escape = tmp_libs[1 - i];
		if (immediate_liberty_count(b, escape) > 2 + NEIGHBOR4(ataristone, escape)) {
			/* Too much free space, ignore. */
			continue;
		}
		liblist[libs++] = i;
	}

	/* Try out the alternatives. */
	bool is_ladder = false;
	for (int i = 0; !is_ladder && i < libs; i++) {
		Board *b2 = b;
		if (i != libs - 1) {
			b2 = bset++;
      CopyBoard(b2, b);
		}

    Coord libs_b2[2];
    get_nlibs_of_group(b2, laddered, 2, libs_b2);

		Coord ataristone = libs_b2[liblist[i]];
		// Coord escape = board_group_info(b2, laddered).lib[1 - liblist[i]];
		struct move m = { ataristone, OPPONENT(lcolor) };
    bool play_successful = TryPlay2(b2, ataristone, &ids);
    if (play_successful) Play(b2, &ids);
		/* If we just played self-atari, abandon ship. */
		/* XXX: If we were very lucky, capturing this stone will
		 * not help us escape. That should be pretty rate. */
    /*
		if (DEBUGL(6))
			fprintf(stderr, "(%d=%d) ladder atari %s (%d libs)\n", i, res, coord2sstr(ataristone, b2), board_group_info(b2, group_at(b2, ataristone)).libs);
    */
		if (play_successful && group_at(b2, ataristone)->liberties > 1) {
      Coord last_lib = get_nlibs_of_group(b2, laddered, 1, NULL);
			is_ladder = middle_ladder_walk(b2, bset, laddered, last_lib, lcolor);
    }

    /* Why we need to do deallocation?
		if (i != libs - 1) {
			board_done_noalloc(b2);
		}
    */
	}
  /*
	if (DEBUGL(6))
		fprintf(stderr, "propagating %d\n", is_ladder);
  */
	return is_ladder;
}
Example #11
0
bool
is_middle_ladder(Board *b, Coord coord, group_t laddered, Stone lcolor)
{
	/* TODO: Remove the redundant parameters. */
	assert(group_at(b, laddered)->liberties == 1);

  Coord last_lib = get_nlibs_of_group(b, laddered, 1, NULL);
	assert(last_lib == coord);
	assert(group_at(b, laddered)->color == lcolor);

	/* If we can move into empty space or do not have enough space
	 * to escape, this is obviously not a ladder. */
	if (immediate_liberty_count(b, coord) != 2) {
    /*
		if (DEBUGL(5))
			fprintf(stderr, "no ladder, wrong free space\n");
    */
		return false;
	}

	/* A fair chance for a ladder. Group in atari, with some but limited
	 * space to escape. Time for the expensive stuff - set up a temporary
	 * board and start selective 2-liberty search. */

	Board *bset = (Board *)malloc(BOARD_MAX_SIZE * 2 * sizeof(Board));

	struct move_queue ccq = { .moves = 0 };
	if (can_countercapture(b, lcolor, laddered, lcolor, &ccq, 0)) {
		/* We could escape by countercapturing a group.
		 * Investigate. */
		assert(ccq.moves > 0);
		for (unsigned int i = 0; i < ccq.moves; i++) {
			Board b2;
			CopyBoard(&b2, b);
			bool is_ladder = middle_ladder_walk(&b2, bset, laddered, ccq.move[i], lcolor);
			// board_done_noalloc(&b2);
			if (!is_ladder) {
				free(bset);
				return false;
			}
		}
	}

	Board b2;
  CopyBoard(&b2, b);
  Coord last_lib2 = get_nlibs_of_group(&b2, laddered, 1, NULL);

	bool is_ladder = middle_ladder_walk(&b2, bset, laddered, last_lib2, lcolor);
	// board_done_noalloc(&b2);
	free(bset);
	return is_ladder;
}

bool
wouldbe_ladder(Board *b, group_t group, Coord escapelib, Coord chaselib, Stone lcolor)
{
	assert(b->_groups[group].liberties == 2);
	assert(b->_groups[group].color == lcolor);

  /*
	if (DEBUGL(6))
		fprintf(stderr, "would-be ladder check - does %s %s play out chasing move %s?\n",
			stone2str(lcolor), coord2sstr(escapelib, b), coord2sstr(chaselib, b));
  */

	if (!NEIGHBOR8(escapelib, chaselib)) {
    /*
		if (DEBUGL(5))
			fprintf(stderr, "cannot determine ladder for remote simulated stone\n");
    */
		return false;
	}

	if (neighbor_count_at(b, chaselib, lcolor) != 1 || immediate_liberty_count(b, chaselib) != 2) {
    /*
		if (DEBUGL(5))
			fprintf(stderr, "overly trivial for a ladder\n");
    */
		return false;
	}

	bool is_ladder = false;
	Board *bset = (Board *)malloc(BOARD_MAX_SIZE * 2 * sizeof(Board));
	Board b2;
	CopyBoard(&b2, b);

  GroupId4 ids;
  if (TryPlay(&b2, X(chaselib), Y(chaselib), OPPONENT(lcolor), &ids)) {
    Play(&b2, &ids);
    Coord last_lib2 = get_nlibs_of_group(&b2, group, 1, NULL);
		is_ladder = middle_ladder_walk(&b2, bset, group, last_lib2, lcolor);
  }

	// board_done_noalloc(&b2);
	free(bset);
	return is_ladder;
}