Example #1
0
void
CmdMove(CORE_DATA *cd)
{
	USER_DATA *ud = UD(cd);

	// the game hasnt started
	if (ud->in_progress == false) {
		Reply("The game has not yet begun");
		return;
	}

	// check for correct arg count
	if (cd->cmd_argc != 2) {
		ReplyFmt("Usage: !move Coord,Coord");
		ReplyFmt("Example: !move e2,e4");
		return;
	}

	// make sure the player is playing
	if (IsPlaying(ud, cd->cmd_name) == false) {
		Reply("You are not playing in this match");
		return;
	}

	// replies to players in-game are via arena

	// check whos turn it is
	if (GetColor(ud, cd->cmd_name) != ud->to_move) {
		ArenaMessage("It is not your move");
		return;
	}
				
	// parse argument
	char xstr[3];
	char ystr[3];
	DelimArgs(xstr, 3, cd->cmd_argv[1], 0, ',', false);
	DelimArgs(ystr, 3, cd->cmd_argv[1], 1, ',', false);

	int x1, y1, x2, y2;
	if (ParseCoords(xstr, &x1, &y1) == true &&
	    ParseCoords(ystr, &x2, &y2) == true) {
		
		char *err = TryMove(ud, ud->to_move, x1, y1, x2, y2);
		if (err == NULL && ud->in_progress == true) {
			// successful moves are announced in TryMove()
			ud->to_move = GetOppositeColor(ud->to_move);
			LvzToMove(ud->to_move, NULL);
			ArenaMessageFmt("%s (%s) to Move",
			    GetPlayerName(ud, ud->to_move), GetColorText(ud->to_move));
		} else if (ud->in_progress == true) {
			ArenaMessageFmt("Couldn't move: %s", err);
		}
	} else {
		ArenaMessageFmt("Invalid coordinates");
	}
}
Example #2
0
void ParseImage( const char* nameFile )
{
    int width, height;
    const char syms[][2] =
    {
        { 'a', 'z' },
        { 'A', 'Z' },
        { 'а', 'я' },
        { 'А', 'Я' },
        { '0', '9' },
        { '+', '+' },
        { '-', '-' },
        { 0, 0 }
    };
    Font* font = InitFont( "Arial", 15, syms );
    uchar* img = LoadImage( nameFile, width, height );
    //DbgMsg( "%d %d", width, height );
    //for( int i = 0; i < 256; i++ )
    //	DbgMsg( "%d - %d", i, colors[i] );
    int colors[2];
    int c_color = GetColorText( img, width, height, colors );
    //оставляем только нужные цвета
    int sz = width * height;
    for( int i = 0; i < sz; i++ )
    {
        int c = 0;
        for( int j = 0; j < c_color; j++ )
            if( img[i] == colors[j] )
            {
                c = 255;
                break;
            }
        img[i] = c;
    }
    const int maxRects = 1000;
    RECT* rects = (RECT*)u_alloc( sizeof(RECT) * maxRects );
    int c_rects = GetRectSymbols( img, width, height, rects, maxRects );

    /*
    for( int i = 0; i < c_rects; i++ )
    {
    	//DbgMsg( "%d %d %d %d", rects[i].left, rects[i].top, rects[i].right, rects[i].bottom );
    	int p1 = rects[i].top * width + rects[i].left;
    	int p2 = rects[i].bottom * width + rects[i].left;
    	for( int x = rects[i].left; x <= rects[i].right; x++, p1++, p2++ )
    	{
    		img[p1] = 128;
    		img[p2] = 128;
    	}
    	p1 = rects[i].top * width + rects[i].left;
    	p2 = rects[i].top * width + rects[i].right;
    	for( int y = rects[i].top; y <= rects[i].bottom; y++, p1 += width, p2 += width )
    	{
    		img[p1] = 128;
    		img[p2] = 128;
    	}
    }
    SaveToBmp( "1_1.bmp", img, width, height );
    */
    char* chars = u_alloc(c_rects);
    for( int i = 0; i < c_rects; i++ )
    {
        uint bits[MaxHeightSymbol];
        RectToBits( img, width, height, rects[i], bits );
        chars[i] = OCRChar( font, bits );
        //DbgMsg( "[%c] %d,%d %d,%d", s, rects[i].left, rects[i].top, rects[i].right, rects[i].bottom );
    }
    //объединяем символы в слова
    Word* words = (Word*)u_alloc( sizeof(Word) * c_rects );
    int c_words = UnionChars( rects, chars, c_rects, words );
    for( int i = 0; i < c_words; i++ )
        DbgMsg( "[%s] %d,%d %d,%d", words[i].w, words[i].r.left, words[i].r.top, words[i].r.right, words[i].r.bottom );
    u_free(words);
    u_free(chars);
    u_free(rects);
    u_free(img);
    ReleaseFont(font);
}
Example #3
0
/*
 * TODO: rewrite this to remove duplicated code
 */
static
char*
TryCastle(USER_DATA *ud, COLOR c, int x, int y, int dx, int dy)
{
	BOARD b = ud->board;
	// coordinates were already verified by IsCastleMove()

	COLOR opp = GetOppositeColor(c);
	if (IsCoordAttackedBy(b, opp, x, y) == true) {
		return "Can't castle out of check";
	}

	if (c == COLOR_WHITE) {
		if (dx == 6) {
			if (IsCoordAttackedBy(b, opp, 5, 0) ||
			    IsCoordAttackedBy(b, opp, 6, 0)) {
				return "Can't castle through or into check";
			}
			if (GetPieceAt(b, 5, 0)->type != TYPE_NONE ||
			    GetPieceAt(b, 6, 0)->type != TYPE_NONE) {
				return "Can't castle through pieces";
			}
			if (GetPieceAt(b, 7, 0)->type != TYPE_ROOK ||
			    GetPieceAt(b, 7, 0)->color != COLOR_WHITE) {
				return "No rook";
			}

			MoveAndReplaceTarget(ud, b, x, y, dx, dy);
			MoveAndReplaceTarget(ud, b, 7, 0, 5, 0);

			ArenaMessageFmt("%s (%s) Moves: Castle kingside",
			    GetPlayerName(ud, c), GetColorText(c));

			return NULL;
		} else if (dx == 2) {
			// castle queenside
			if (IsCoordAttackedBy(b, opp, 2, 0) ||
			    IsCoordAttackedBy(b, opp, 3, 0)) {
				return "Can't castle through or into check";
			}
			if (GetPieceAt(b, 1, 0)->type != TYPE_NONE ||
			    GetPieceAt(b, 2, 0)->type != TYPE_NONE ||
			    GetPieceAt(b, 3, 0)->type != TYPE_NONE) {
				return "Can't castle through pieces";
			}
			if (GetPieceAt(b, 0, 0)->type != TYPE_ROOK ||
			    GetPieceAt(b, 0, 0)->color != COLOR_WHITE) {
				return "No rook";
			}

			MoveAndReplaceTarget(ud, b, x, y, dx, dy);
			MoveAndReplaceTarget(ud, b, 0, 0, 3, 0);

			ArenaMessageFmt("%s (%s) Moves: Castle queenside",
			    GetPlayerName(ud, c), GetColorText(c));

			return NULL;
		}
	} else if (c == COLOR_BLACK) {
		if (dx == 6) {
			// castle kingside
			if (IsCoordAttackedBy(b, opp, 5, 7) ||
			    IsCoordAttackedBy(b, opp, 6, 7)) {
				return "Can't castle through or into check";
			}
			if (GetPieceAt(b, 5, 7)->type != TYPE_NONE ||
			    GetPieceAt(b, 6, 7)->type != TYPE_NONE) {
				return "Can't castle through pieces";
			}
			if (GetPieceAt(b, 7, 7)->type != TYPE_ROOK ||
			    GetPieceAt(b, 7, 7)->color != COLOR_BLACK) {
				return "No rook";
			}

			MoveAndReplaceTarget(ud, b, x, y, dx, dy);
			MoveAndReplaceTarget(ud, b, 7, 7, 5, 7);

			ArenaMessageFmt("%s (%s) Moves: Castle kingside",
			    GetPlayerName(ud, c), GetColorText(c));

			return NULL;
		} else if (dx == 2) {
			// castle queenside
			if (IsCoordAttackedBy(b, opp, 2, 7) ||
			    IsCoordAttackedBy(b, opp, 3, 7)) {
				return "Can't castle through or into check";
			}
			if (GetPieceAt(b, 1, 7)->type != TYPE_NONE ||
			    GetPieceAt(b, 2, 7)->type != TYPE_NONE ||
			    GetPieceAt(b, 3, 7)->type != TYPE_NONE) {
				return "Can't castle through pieces";
			}
			if (GetPieceAt(b, 0, 7)->type != TYPE_ROOK ||
			    GetPieceAt(b, 0, 7)->color != COLOR_BLACK) {
				return "No rook";
			}

			MoveAndReplaceTarget(ud, b, x, y, dx, dy);
			MoveAndReplaceTarget(ud, b, 0, 7, 3, 7);

			ArenaMessageFmt("%s (%s) Moves: Castle queenside",
			    GetPlayerName(ud, c), GetColorText(c));

			return NULL;
		}

	} else {
		return "Error castling";
	}

	return "Could not castle";
}
Example #4
0
// TODO: Handle en passant
static
char*
TryMove(USER_DATA *ud, COLOR c, int x, int y, int dx, int dy)
{
	BOARD b = ud->board;

	PIECE *p = GetPieceAt(ud->board, x, y);
	if (p->type == TYPE_NONE) {
		return "No piece at that position!";
	} else if (p->color != c) {
		return "That piece is not yours!";
	}

	// check if this move is a castle attempt
	// TODO: check for rook movements
	if (p->type == TYPE_KING && IsCastleMove(c, x, y, dx, dy)) {
		if (ColorCanCastle(ud, c) == false) {
			return "You can no longer castle";
		}
		
		return TryCastle(ud, c, x, y, dx, dy);
	}

	// check that the piece can make this movement
	if (PieceCanAttack(ud->board, c, p->type, x, y, dx, dy) == false) {
		return "Piece can't make that movement";
	}

	// target piece
	PIECE *t = GetPieceAt(ud->board, dx, dy);
	if (t->type != TYPE_NONE && t->color == c) {
		return "You already have a piece in the destination position!";
	}

	// make the movements to check for check, but store the data
	// in case the board needs to be reverted
	PIECE old_p = *p;
	PIECE old_t = *t;
	SetPieceAt(b, dx, dy, p->color, p->type);
	SetPieceAt(b, x, y, COLOR_NONE, TYPE_NONE);

	// find the king and test for check
	int kingx, kingy;
	FindKing(b, c, &kingx, &kingy);
	if (IsCoordAttackedBy(b, GetOppositeColor(c), kingx, kingy) == true) {
		// restore saved positions
		SetPieceAt(b, x, y, old_p.color, old_p.type);
		SetPieceAt(b, dx, dy, old_t.color, old_t.type);
		return "That move would place your King in check!";
	}

	//
	// At this point, the move was successful
	//

	// make the pieces blink
	// TODO: this will erroneously leave pieces on if 2 moves
	// are made quickly
	uint32_t objid = LvzGetObjId(old_p.color, old_p.type, dx, dy);
	SetTimer(500, (void*)objid, (void*)0);
	SetTimer(1000, (void*)objid, (void*)1);
	SetTimer(1500, (void*)objid, (void*)0);
	SetTimer(2000, (void*)objid, (void*)1);
	SetTimer(2500, (void*)objid, (void*)0);
	SetTimer(3000, (void*)objid, (void*)1);
	if (old_t.type != TYPE_NONE) {
		// flash the captured piece
		objid = LvzGetObjId(old_t.color, old_t.type, dx, dy);
		SetTimer(500, (void*)objid, (void*)1);
		SetTimer(1000, (void*)objid, (void*)0);
		SetTimer(1500, (void*)objid, (void*)1);
		SetTimer(2000, (void*)objid, (void*)0);
		SetTimer(2500, (void*)objid, (void*)1);
		SetTimer(3000, (void*)objid, (void*)0);
	}

	if (old_p.type == TYPE_KING) {
		// kings cant castle once theyve moved
		if (old_p.color == COLOR_WHITE) {
			ud->white_can_castle = false;
		} else if (old_p.color == COLOR_BLACK) {
			ud->black_can_castle = false;
		}
	}

	// set if a piece has been captured
	bool capture = old_t.type != TYPE_NONE;

	// remove drawing of the old pieces
	LvzActivate(ud, NULL, old_p.color, old_p.type, x, y, false);
	if (capture) {
		LvzActivate(ud, NULL, old_t.color, old_t.type, dx, dy, false);
	}

	// check for pawn promotions
	// TODO: handle underpromotions
	bool promoted = false;
	p = GetPieceAt(b, dx, dy);
	if (p->type == TYPE_PAWN) {
		if (p->color == COLOR_WHITE && dy == 7) {
			p->type = TYPE_QUEEN;
			promoted = true;
		} else if (p->color == COLOR_BLACK && dy == 0) {
			p->type = TYPE_QUEEN;
			promoted = true;
		}
	}

	// draw the new piece
	LvzActivate(ud, NULL, old_p.color, old_p.type, dx, dy, true);
	objid = LvzGetObjId(old_p.color, old_p.type, dx, dy);

	// create move notation
	char move[6];
	move[0] = x + 'a';
	move[1] = y + '1';
	move[2] = ',';
	move[3] = dx + 'a';
	move[4] = dy + '1';
	move[5] = '\0';

	// announce the move
	char line[256];
	snprintf(line, 256, "%s (%s) Moves: %s",
	    GetPlayerName(ud, c), GetColorText(ud->to_move), move);
	if (capture) {
		// add capture line
		char capture[64];
		snprintf(capture, 64, ", capturing a %s!", GetTypeName(old_t.type));
		strlcat(line, capture, 256);
	}
	if (promoted == true) {
		// add promition line
		strlcat(line, " Pawn promoted to Queen!", 256);
	}
	FindKing(b, GetOppositeColor(c), &kingx, &kingy);
	if (IsCoordAttackedBy(b, c, kingx, kingy) == true) {
		if (IsCheckmatedBy(b, c, kingx, kingy) == true) {
			strlcat(line, " Checkmate!", 256);
			ArenaMessage(line);

			char gametime[32];
			TicksToText(gametime, 32, GetTicksMs() - ud->start_tick);
			StopGame(ud, "%s Wins in %s!", GetPlayerName(ud, c), gametime);
		} else {
			strlcat(line, " Check!", 256);
			ArenaMessage(line);
		}
	} else {
		ArenaMessage(line);
	}

	return NULL;
}