Exemple #1
0
int main ( int argc, char *argv[] )
{
    gettextinfo ( &StartupTextInfo );
    atexit ( exitcode );

    extern bool sound_flag;
    sound_flag = true;

    printf (
        "\n"
        "MailChess v %s by Don Cross <*****@*****.**>, 1 March 1996.\n"
        "http://www.intersrv.com/~dcross\n"
        "\n",
        MailChess_Version );

    const char * const help =
        "Use:  MAILCHES mailfile\n"
        "\n"
        "This program helps two people play chess by e-mail.  MailChess reads\n"
        "and writes a text file which can be sent back and forth by email.\n"
        "MailChess ignores e-mail headers and other extraneous text.\n"
        "\n"
        "If 'mailfile' exists, it is scanned for chess data and MailChess tries\n"
        "to restore a game in progress so that the next move can be made.\n"
        "\n"
        "If 'mailfile' does not exist, MailChess assumes that you want to\n"
        "start a new game, and that you will play White.\n"
        "In this case, you will make your first move and MailChess will\n"
        "create the file 'mailfile'.\n";

//  "If the optional parameter 'listfile' is specified, MailChess will\n"
//  "read the game encoded in 'mailfile' and create a human-readable\n"
//  "listing of the game in 'listfile', then immediately exit.\n";

    if ( argc != 2 && argc != 3 )
    {
        printf ( "%s", help );
        return 1;
    }

    ChessBoard theBoard;

    if ( argc == 3 )
    {
        if ( !ReadEmail ( 0, theBoard, argv[1] ) )
        {
            fprintf ( stderr, "No valid chess data in file '%s'\n", argv[1] );
            return 1;
        }

        FILE *out = fopen ( argv[2], "wt" );
        if ( !out )
        {
            fprintf ( stderr, "Cannot open file '%s' for write!\n", argv[2] );
            return 1;
        }

        ListChessGame ( theBoard, out );

        fclose ( out );
        printf ( "Game listing written to file '%s'\n", argv[2] );
        return 0;
    }

    ChessUI_dos_cga theUserInterface;

    ChessPlayer *player = new HumanChessPlayer ( theUserInterface );
    if ( !player )
    {
        fprintf ( stderr, "Error:  Not enough memory to run this program!\n" );
        return 1;
    }

    if ( !ReadEmail ( &theUserInterface, theBoard, argv[1] ) )
    {
        fprintf ( stderr, "The file '%s' does not exist.\n", argv[1] );
        fprintf ( stderr, "Do you want to start a new game and create '%s'?\n", argv[1] );
        fprintf ( stderr, "(y/n):  " );
        fflush ( stderr );
        char answer [20];
        answer[0] = '\0';
        fgets ( answer, sizeof(answer), stdin );
        if ( answer[0]!='y' && answer[0]!='Y' )
        {
            delete player;
            return 1;
        }
    }

    MoveList legalMoveList;
    ChessSide winner = SIDE_NEITHER;
    if ( theBoard.WhiteToMove() )
    {
        theBoard.GenWhiteMoves ( legalMoveList );
        if ( legalMoveList.num == 0 )
        {
            winner = theBoard.WhiteInCheck() ? SIDE_BLACK : SIDE_NEITHER;
        }
    }
    else
    {
        theBoard.GenBlackMoves ( legalMoveList );
        if ( legalMoveList.num == 0 )
        {
            winner = theBoard.BlackInCheck() ? SIDE_WHITE : SIDE_NEITHER;
        }
    }

    bool gameIsOver = (legalMoveList.num == 0);
    if ( !gameIsOver )
    {
        // Look for definite draws...

        if ( theBoard.IsDefiniteDraw(3) )
        {
            winner = SIDE_NEITHER;
            gameIsOver = true;
        }
    }

    // Now, 'gameIsOver' definitely has the correct value.

    if ( gameIsOver )
    {
        // Display the ending state of the game and let the
        // user gloat/sulk/sigh.

        HelpUser_EndOfGame ( winner );
        while ( (bioskey(0) & 0xff) != 0x1b );
        sprintf ( ExitMessage,
                  "This game is over.  MailChess has not changed '%s'.\n",
                  argv[1] );
    }
    else
    {
        // Read a single move from the user.
        // Ask the user if he/she is sure afterward.
        // If not, cancel the move and let them do another.
        // Otherwise, commit to the move, write the updated game
        // state to the text file, and exit.

        HelpUser_MakeMove();

        for(;;)
        {
            Move move;
            INT32 timeSpent = 0;

            bool moveWasRead = player->GetMove (
                                   theBoard,
                                   move,
                                   timeSpent );

            if ( moveWasRead )
            {
                theUserInterface.RecordMove ( theBoard, move, timeSpent );
                UnmoveInfo unmove;
                theBoard.MakeMove ( move, unmove );
                theUserInterface.DrawBoard ( theBoard );

                int promptY = theBoard.WhiteToMove() ? 25 : 24;

                gotoxy ( 20, promptY );
                printf ( "Are you sure this is the move you want to make? (Y/N) " );
                unsigned key = 0;
                while ( toupper(key) != 'Y' && toupper(key) != 'N' )
                {
                    key = bioskey(0) & 0xff;
                }

                if ( key == 'Y' || key == 'y' )
                {
                    WriteEmail ( theBoard, argv[1] );
                    sprintf ( ExitMessage, "Your move has been added to the file '%s'.\n", argv[1] );
                    break;
                }
                else
                {
                    gotoxy ( 1, promptY );
                    printf ( "                                                                          " );
                    theBoard.UnmakeMove ( move, unmove );
                    theUserInterface.DrawBoard ( theBoard );
                }
            }
            else
            {
                sprintf ( ExitMessage, "The file '%s' has not been changed.\n", argv[1] );
                break;
            }
        }
    }

    delete player;

    return 0;
}