Beispiel #1
0
static game_state *execute_move(game_state *from, char *move)
{
    int w = from->par.w, a = w*w;
    game_state *ret;
    int x, y, i, n;

    if (move[0] == 'S') {
	ret = dup_game(from);
	ret->completed = ret->cheated = TRUE;

	for (i = 0; i < a; i++) {
	    if (move[i+1] < '1' || move[i+1] > '0'+w) {
		free_game(ret);
		return NULL;
	    }
	    ret->grid[i] = move[i+1] - '0';
	    ret->pencil[i] = 0;
	}

	if (move[a+1] != '\0') {
	    free_game(ret);
	    return NULL;
	}

	return ret;
    } else if ((move[0] == 'P' || move[0] == 'R') &&
	sscanf(move+1, "%d,%d,%d", &x, &y, &n) == 3 &&
	x >= 0 && x < w && y >= 0 && y < w && n >= 0 && n <= w) {
	if (from->clues->immutable[y*w+x])
	    return NULL;

	ret = dup_game(from);
        if (move[0] == 'P' && n > 0) {
            ret->pencil[y*w+x] ^= 1L << n;
        } else {
            ret->grid[y*w+x] = n;
            ret->pencil[y*w+x] = 0;

            if (!ret->completed && !check_errors(ret, NULL))
                ret->completed = TRUE;
        }
	return ret;
    } else if (move[0] == 'M') {
	/*
	 * Fill in absolutely all pencil marks everywhere. (I
	 * wouldn't use this for actual play, but it's a handy
	 * starting point when following through a set of
	 * diagnostics output by the standalone solver.)
	 */
	ret = dup_game(from);
	for (i = 0; i < a; i++) {
	    if (!ret->grid[i])
		ret->pencil[i] = (1L << (w+1)) - (1L << 1);
	}
	return ret;
    } else
	return NULL;		       /* couldn't parse move string */
}
Beispiel #2
0
/**
 * Handle button 'Quit'.
 * Closes window.
 */
int on_select_quit(Control* btn_quit) {
	if (game != NULL) {
		free_game(game);
		game = NULL;
	}
	return 1;
}
int main(void)
{
    TicTacToe game;
    int size;

    printf("This is the game of Tic Tac Toe.\n");
    printf("You will be playing against the computer.\n");

    printf("Enter the size of the board: ");
    scanf("%d", &size);
    printf("The game board is %d by %d.\n", size, size);

    init_game(&game, size); // initialise the board

    int done;
    do {
        print_game(game);
        do {
            done = player_move(&game);
        } while (!done); // loop until valid move
        if(check(&game) != FALSE) break; // was a winner or a draw
        computer_move(&game);
        if(check(&game) != FALSE) break; // was a winner or a draw
    } while (TRUE);

    print_result(game);
    print_game(game); // show final positions

    free_game(&game);

    return 0;
}
Beispiel #4
0
/**
 * Returns to main menu without creating game.
 */
int on_cancel(Control* btn) {
	int (*handles[4])(Control*) = {
		empty_select, on_new_game, on_load_game, on_select_quit };
	if (game != NULL) {
		free_game(game);
		game = NULL;
	}
	return !show_main_menu(get_root(btn), handles);
}
Beispiel #5
0
static int proto_cli_leave_home_op(home_t* p_home, sprite_ol_t* p, void* data)
{
	hero_cup_game_t* game = NULL;
	home_proto_t* p_proto = data;
	client_proto_t *cli = (client_proto_t*)p_proto->body;
	CHECK_BODY_LEN(p_proto->len, 20 + sizeof(home_proto_t) + sizeof(client_proto_t));

	int i = 12;
	mapid_t newmap = 0;
	unpkg_mapid(cli->body,&newmap,&i);
	mapid_t gameid = (p_home->homeid & 0xFFFFFFFF00000000) | hero_cup_game_map;

	tranfer_to_home(p_home, data, p_proto->len);
	free_sprite_ol(p_home, p);

	if((gameid >> 56) != 0xFE) return 0;
	game = g_hash_table_lookup(all_games,&gameid);
	if(!game) {
		KDEBUG_LOG(p_proto->id,"LEAVE HOME: game(%x.%u) NOT EXSIT!",HI32(gameid),LO32(gameid));
		return 0;
	}

	game->active--;
	if((newmap >> 56) != 0xFE) {
		if(game->active == 0) {
			free_game(NULL,game,NULL);
			return 0;
		}
	}

	attacker_t *atker = get_attacker(game,p_proto->id);
	if(!atker) {
		KDEBUG_LOG(p_proto->id,"LEAVE HOME: uid not in game(%x.%u)",HI32(gameid),LO32(gameid));
		return 0;
	}

	if(atker->atkpos < 12) {
		position_t *weapon = &game->weapon[atker->atkpos];
		if(weapon->uid == atker->userid) {
			weapon->state |= 1;
			weapon->card = 0;
		} else {
			weapon->state |= 2;
			weapon->atk_card = 0;
		}
		play_card_result(game,atker->atkpos);
	}

	if((newmap >> 56) != 0xFE) {
		del_attacker(game->group,atker->userid);
	}

	return 0;
}
Beispiel #6
0
void free_all_chess_games( void )
{
    list < char_data * >::iterator ich;

    for( ich = pclist.begin(  ); ich != pclist.end(  ); ++ich )
    {
        char_data *ch = *ich;

        free_game( ch->pcdata->game_board );
    }
}
int main(int argc, char *argv[]) {
	int CONTINUE,WINNER,HUMAN,COMPUTER;

	if(argc!=4) {
		fprintf(stderr,"Usage: mnkgame <row> <col> <k>\n");
		return 1;
	}
	if(!read_parameters(argv)) return 1;

	if(!setup_game(M,N,K)) {
		fprintf(stderr,"Error: the board is too big!\n");
		return 1;
	}

	COMPUTER=1;
	HUMAN=2;

	setup_player(M,N,K);
	printf("Computer Player ready\n");
	mypause();

	CONTINUE=N*M;
  WINNER=DRAW;

	while(CONTINUE>0) {
		if(read_move(PLAYER1,HUMAN)) {
			WINNER=PLAYER1;
			CONTINUE=0;
		}
		if(--CONTINUE>0) {
			if(read_move(PLAYER2,HUMAN)) {
				WINNER=PLAYER2;
				CONTINUE=0;
			}
			--CONTINUE;
		}
	}
	system("cls");
	print_board();
	end_game(WINNER,HUMAN);


	free_player();
	free_game();

	return 0;
}
void game_done(void)
{
#ifdef CLEANUP_CODE
    /* Diese Routine enfernt allen allokierten Speicher wieder. Das ist nur
     * zum Debugging interessant, wenn man Leak Detection hat, und nach
     * nicht freigegebenem Speicher sucht, der nicht bis zum Ende benötigt
     * wird (temporäre Hilsstrukturen) */

    free_game();

    creport_cleanup();
#ifdef REPORT_FORMAT_NR
    report_cleanup();
#endif
    calendar_cleanup();
#endif
    free_functions();
    curses_done();
    kernel_done();
}
Beispiel #9
0
void do_chess( CHAR_DATA * ch, const char *argument )
{
	char arg[MAX_INPUT_LENGTH];

	argument = one_argument( argument, arg );

	if ( IS_NPC( ch ) )
	{
		send_to_char( "NPC's can't be in chess games.\r\n", ch );
		return;
	}

	if ( !str_cmp( arg, "begin" ) )
	{
		GAME_BOARD_DATA *board;

		if ( ch->pcdata->game_board )
		{
			send_to_char( "You are already in a chess match.\r\n", ch );
			return;
		}

		CREATE( board, GAME_BOARD_DATA, 1 );
		init_board( board );
		ch->pcdata->game_board = board;
		ch->pcdata->game_board->player1 = QUICKLINK( ch->name );
		send_to_char( "You have started a game of chess.\r\n", ch );
		return;
	}

	if ( !str_cmp( arg, "join" ) )
	{
		GAME_BOARD_DATA *board = NULL;
		CHAR_DATA *vch;
		char arg2[MAX_INPUT_LENGTH];

		if ( ch->pcdata->game_board )
		{
			send_to_char( "You are already in a game of chess.\r\n", ch );
			return;
		}

		argument = one_argument( argument, arg2 );
		if ( arg2[0] == '\0' )
		{
			send_to_char( "Join whom in a chess match?\r\n", ch );
			return;
		}

#ifdef IMC
		if ( strstr( arg2, "@" ) )
		{
			if ( !str_cmp( imc_mudof( arg2 ), this_imcmud->localname ) )
			{
				send_to_char( "You cannot join IMC chess on the local mud!\r\n", ch );
				return;
			}

			if ( !str_cmp( imc_mudof( arg2 ), "*" ) )
			{
				send_to_char( "* is not a valid mud name.\r\n", ch );
				return;
			}

			if ( !str_cmp( imc_nameof( arg2 ), "*" ) )
			{
				send_to_char( "* is not a valid player name.\r\n", ch );
				return;
			}

			send_to_char( "Attempting to initiate IMC chess game...\r\n", ch );

			CREATE( board, GAME_BOARD_DATA, 1 );
			init_board( board );
			board->type = TYPE_IMC;
			board->player1 = QUICKLINK( ch->name );
			board->player2 = STRALLOC( arg2 );
			board->turn = -1;
			ch->pcdata->game_board = board;
			imc_send_chess( ch->name, arg2, "start" );
			return;
		}
#endif

		if ( !( vch = get_char_world( ch, arg2 ) ) )
		{
			send_to_char( "Cannot find that player.\r\n", ch );
			return;
		}

		if ( IS_NPC( vch ) )
		{
			send_to_char( "That player is an NPC, and cannot play games.\r\n", ch );
			return;
		}

		board = vch->pcdata->game_board;
		if ( !board )
		{
			send_to_char( "That player is not playing a game.\r\n", ch );
			return;
		}

		if ( board->player2 )
		{
			send_to_char( "That game already has two players.\r\n", ch );
			return;
		}

		board->player2 = QUICKLINK( ch->name );
		ch->pcdata->game_board = board;
		send_to_char( "You have joined a game of chess.\r\n", ch );

		vch = get_char_world( ch, board->player1 );
		ch_printf( vch, "%s has joined your game.\r\n", ch->name );
		return;
	}

	if ( !ch->pcdata->game_board )
	{
		send_to_char( "Usage: chess <begin|cease|status|board|move|join>\r\n", ch );
		return;
	}

	if ( !str_cmp( arg, "cease" ) )
	{
		free_game( ch->pcdata->game_board );
		return;
	}

	if ( !str_cmp( arg, "status" ) )
	{
		GAME_BOARD_DATA *board = ch->pcdata->game_board;

		if ( !board->player1 )
			send_to_char( "There is no black player.\r\n", ch );
		else if ( !str_cmp( board->player1, ch->name ) )
			send_to_char( "You are black.\r\n", ch );
		else
			ch_printf( ch, "%s is black.\r\n", board->player1 );

		if ( king_in_checkmate( board, BLACK_KING ) )
			send_to_char( "The black king is in checkmate!\r\n", ch );
		else if ( king_in_check( board, BLACK_KING ) )
			send_to_char( "The black king is in check.\r\n", ch );

		if ( !board->player2 )
			send_to_char( "There is no white player.\r\n", ch );
		else if ( !str_cmp( board->player2, ch->name ) )
			send_to_char( "You are white.\r\n", ch );
		else
			ch_printf( ch, "%s is white.\r\n", board->player2 );

		if ( king_in_checkmate( board, WHITE_KING ) )
			send_to_char( "The white king is in checkmate!\r\n", ch );
		else if ( king_in_check( board, WHITE_KING ) )
			send_to_char( "The white king is in check.\r\n", ch );

		if ( !board->player2 || !board->player1 )
			return;

		ch_printf( ch, "%d turns.\r\n", board->turn );
		if ( board->turn % 2 == 1 && !str_cmp( board->player1, ch->name ) )
		{
			ch_printf( ch, "It is %s's turn.\r\n", board->player2 );
			return;
		}
		else if ( board->turn % 2 == 0 && !str_cmp( board->player2, ch->name ) )
		{
			ch_printf( ch, "It is %s's turn.\r\n", board->player1 );
			return;
		}
		else
		{
			send_to_char( "It is your turn.\r\n", ch );
			return;
		}
		return;
	}

	if ( !str_prefix( arg, "board" ) )
	{
		send_to_char( print_big_board( ch, ch->pcdata->game_board ), ch );
		return;
	}

	if ( !str_prefix( arg, "move" ) )
	{
		CHAR_DATA *opp;
		char opp_name[MAX_INPUT_LENGTH];
		char a, b;
		int x, y, dx, dy, ret;

		if ( !ch->pcdata->game_board->player1 || !ch->pcdata->game_board->player2 )
		{
			send_to_char( "There is only 1 player.\r\n", ch );
			return;
		}

		if ( ch->pcdata->game_board->turn < 0 )
		{
			send_to_char( "The game hasn't started yet.\r\n", ch );
			return;
		}

		if ( king_in_checkmate( ch->pcdata->game_board, BLACK_KING ) )
		{
			send_to_char( "The black king has been checkmated, the game is over.\r\n", ch );
			return;
		}

		if ( king_in_checkmate( ch->pcdata->game_board, WHITE_KING ) )
		{
			send_to_char( "The white king has been checkmated, the game is over.\r\n", ch );
			return;
		}

		if ( !*argument )
		{
			send_to_char( "Usage: chess move [piece to move] [where to move]\r\n", ch );
			return;
		}

		if ( ch->pcdata->game_board->turn % 2 == 1 && !str_cmp( ch->pcdata->game_board->player1, ch->name ) )
		{
			send_to_char( "It is not your turn.\r\n", ch );
			return;
		}

		if ( ch->pcdata->game_board->turn % 2 == 0 && !str_cmp( ch->pcdata->game_board->player2, ch->name ) )
		{
			send_to_char( "It is not your turn.\r\n", ch );
			return;
		}

		if ( sscanf( argument, "%c%d %c%d", &a, &y, &b, &dy ) != 4 )
		{
			send_to_char( "Usage: chess move [dest] [source]\r\n", ch );
			return;
		}

		if ( a < 'a' || a > 'h' || b < 'a' || b > 'h' || y < 1 || y > 8 || dy < 1 || dy > 8 )
		{
			send_to_char( "Invalid move, use a-h, 1-8.\r\n", ch );
			return;
		}

		x = a - 'a';
		dx = b - 'a';
		--y;
		--dy;

		ret = is_valid_move( ch, ch->pcdata->game_board, x, y, dx, dy );
		if ( ret == MOVE_OK || ret == MOVE_TAKEN )
		{
			GAME_BOARD_DATA *board;
			int piece, destpiece;

			board = ch->pcdata->game_board;
			piece = board->board[x][y];
			destpiece = board->board[dx][dy];
			board->board[dx][dy] = piece;
			board->board[x][y] = NO_PIECE;

			if ( king_in_check( board, IS_WHITE( board->board[dx][dy] ) ? WHITE_KING : BLACK_KING ) && ( board->board[dx][dy] != WHITE_KING && board->board[dx][dy] != BLACK_KING ) )
			{
				board->board[dx][dy] = destpiece;
				board->board[x][y] = piece;
				ret = MOVE_INCHECK;
			}
			else
			{
				++board->turn;
#ifdef IMC
				if ( ch->pcdata->game_board->type == TYPE_IMC )
				{
					snprintf( arg, LGST, "move %d%d %d%d", x, y, dx, dy );
					imc_send_chess( ch->pcdata->game_board->player1, ch->pcdata->game_board->player2, arg );
				}
#endif
			}
		}

		if ( !str_cmp( ch->name, ch->pcdata->game_board->player1 ) )
		{
			opp = get_char_world( ch, ch->pcdata->game_board->player2 );
			if ( !opp )
				mudstrlcpy( opp_name, ch->pcdata->game_board->player2, MAX_INPUT_LENGTH );
		}
		else
		{
			opp = get_char_world( ch, ch->pcdata->game_board->player1 );
			if ( !opp )
				mudstrlcpy( opp_name, ch->pcdata->game_board->player1, MAX_INPUT_LENGTH );
		}

#ifdef IMC
#    define SEND_TO_OPP(arg,opp) \
      if( opp ) \
      { \
         if( ch->pcdata->game_board->type == TYPE_LOCAL ) \
            ch_printf( (opp), "%s\r\n", (arg) ); \
      } \
      else \
      { \
         if( ch->pcdata->game_board->type == TYPE_IMC ) \
            imc_send_tell( ch->name, opp_name, (arg), 1 ); \
      }
#else
#    define SEND_TO_OPP(arg,opp) \
      if( opp ) \
      { \
         if( ch->pcdata->game_board->type == TYPE_LOCAL ) \
            ch_printf( (opp), "%s\r\n", (arg) ); \
      }
#endif

		switch ( ret )
		{
			case MOVE_OK:
				send_to_char( "Ok.\r\n", ch );
				snprintf( arg, MAX_INPUT_LENGTH, "%s has moved.\r\n", ch->name );
				SEND_TO_OPP( arg, opp );
				break;

			case MOVE_INVALID:
				send_to_char( "Invalid move.\r\n", ch );
				break;

			case MOVE_BLOCKED:
				send_to_char( "You are blocked in that direction.\r\n", ch );
				break;

			case MOVE_TAKEN:
				send_to_char( "You take the enemy's piece.\r\n", ch );
				snprintf( arg, MAX_INPUT_LENGTH, "%s has taken one of your pieces!", ch->name );
				SEND_TO_OPP( arg, opp );
				break;

			case MOVE_CHECKMATE:
				send_to_char( "That move would result in a checkmate.\r\n", ch );
				snprintf( arg, MAX_INPUT_LENGTH, "%s has attempted a move that would result in checkmate.", ch->name );
				SEND_TO_OPP( arg, opp );
				break;

			case MOVE_OFFBOARD:
				send_to_char( "That move would be off the board.\r\n", ch );
				break;

			case MOVE_SAMECOLOR:
				send_to_char( "Your own piece blocks the way.\r\n", ch );
				break;

			case MOVE_CHECK:
				send_to_char( "That move would result in a check.\r\n", ch );
				snprintf( arg, MAX_INPUT_LENGTH, "%s has made a move that would result in a check.", ch->name );
				SEND_TO_OPP( arg, opp );
				break;

			case MOVE_WRONGCOLOR:
				send_to_char( "That is not your piece.\r\n", ch );
				break;

			case MOVE_INCHECK:
				send_to_char( "You are in check, you must save your king.\r\n", ch );
				break;

			default:
				bug( "%s: Unknown return value", __FUNCTION__ );
				break;
		}
#undef SEND_TO_OPP
		return;
	}
	send_to_char( "Usage: chess <begin|cease|status|board|move|join>\r\n", ch );
}
Beispiel #10
0
int main(int argc, const char *argv[])
{
    mt_seed();
    unsigned int i,j;
    unsigned int total_games=100;
    double b;

    unsigned int **count;
    unsigned int **count_aux;
    count=malloc(total_games*sizeof(unsigned int *));
    count_aux=malloc(total_games*sizeof(unsigned int *));

    unsigned int **coop_cluster;
    coop_cluster=malloc(total_games*sizeof(unsigned int *));
    for (i = 0; i < total_games; i++)
        coop_cluster[i]=NULL;
    double coop_mean;
    double coop_fixed_mean;
    double coop_isolated_mean;
    double coop_cluster_mean;
    double coop_effective_surface_mean;

    unsigned int **def_cluster;
    def_cluster=malloc(total_games*sizeof(unsigned int *));
    for (i = 0; i < total_games; i++)
        def_cluster[i]=NULL;
    double def_mean;
    double def_fixed_mean;
    double def_isolated_mean;
    double def_cluster_mean;
    double def_effective_surface_mean;
    
    unsigned int *iter;
    unsigned int iter0=5000;
    unsigned int iter1;
    unsigned int iter_mean;
    iter=malloc(total_games*sizeof(unsigned int));

    FILE *f;
    f=fopen("data_iter2.csv","w");
    fprintf(f,"b\t");
    fprintf(f,"coop_mean\tcoop_fixed_mean\tcoop_isolated_mean\tcoop_cluster_mean\tcoop_effective_surface_mean\t");
    fprintf(f,"def_mean\tdef_fixed_mean\tdef_isolated_mean\tdef_cluster_mean\tdef_effective_surface_mean\t");
    fprintf(f,"iter_mean\n");
    fclose(f);

    struct game gam;
    struct game *g_aux;
    g_aux=&gam;

    for (b = 1.5; b < 2.0; b+=0.05)
    {
        for (j = 0; j < total_games;) 
        {
            gam=create_prisioner_dilemma_game(b,4000,8000,1);

            for (i = 0; i < iter0; i++)
                evolve_game(g_aux,0);
            iter[j]=iter0;

            iter1=1000;
            do
            {
                count[j]=count_type(gam);
                for (i = 0; i < iter1; i++)
                    evolve_game(g_aux,0);
                iter[j]+=iter1;
                count_aux[j]=count_type(gam);
            }
            while (abs(count[j][0]-count_aux[j][0])>10);

            iter1=10000;
            for (i = 0; i < iter1; i++)
                evolve_game(g_aux,0);
                
            iter1=1000;
            for (i = 0; i < iter1; i++)
                evolve_game(g_aux,1);

            free(count[j]);
            free(coop_cluster[j]);
            free(def_cluster[j]);

            count[j]=count_type(gam);
            coop_cluster[j]=cluster_analize(gam,0);
            def_cluster[j]=cluster_analize(gam,1);
/*
            if(coop_cluster[j][2]==0)
                printf("b: %.3lf game: %u FAILED, COOPERATORS DESTROYED\n",b,j);
            else if(def_cluster[j][2]==0)
                printf("b: %.3lf game: %u FAILED, DEFECTORS DESTROYED\n",b,j);
            else
            {*/
                printf("b: %.3lf game: %u DONE\n",b,j);
                j++;
            //}

            //graph_to_file("grafo.gdf",gam.g,1);

            free_game(g_aux);
        }

        coop_mean=0;
        coop_fixed_mean=0;
        coop_isolated_mean=0;
        coop_cluster_mean=0;
        coop_effective_surface_mean=0;

        def_mean=0;
        def_fixed_mean=0;
        def_isolated_mean=0;
        def_cluster_mean=0;
        def_effective_surface_mean=0;

        iter_mean=0;
        for (i = 0; i < total_games; i++)
        {
            coop_mean+=(double)count[i][0]/total_games;
            coop_fixed_mean+=(double)coop_cluster[i][2]/total_games;
            coop_isolated_mean+=(double)coop_cluster[i][4]/total_games;
            coop_cluster_mean+=(double)(coop_cluster[i][0]-coop_cluster[i][1])/total_games;
            coop_effective_surface_mean+=(double)coop_cluster[i][3]/(coop_cluster[i][2]-coop_cluster[i][4])/total_games;

            def_mean+=(double)count[i][1]/total_games;
            def_fixed_mean+=(double)def_cluster[i][2]/total_games;
            def_isolated_mean+=(double)def_cluster[i][4]/total_games;
            def_cluster_mean+=(double)(def_cluster[i][0]-def_cluster[i][1])/total_games;
            def_effective_surface_mean+=(double)def_cluster[i][3]/(def_cluster[i][2]-def_cluster[i][4])/total_games;

            iter_mean+=iter[i]/total_games;
        }

        coop_mean/=4000.;
        coop_fixed_mean/=4000.;
        coop_isolated_mean/=4000.;

        def_mean/=4000.;
        def_fixed_mean/=4000.;
        def_isolated_mean/=4000.;

        f=fopen("data_iter2.csv","a");
        fprintf(f,"%lf\t",b);
        fprintf(f,"%lf\t%lf\t%lf\t%lf\t%lf\t",coop_mean,coop_fixed_mean,coop_isolated_mean,coop_cluster_mean,coop_effective_surface_mean);
        fprintf(f,"%lf\t%lf\t%lf\t%lf\t%lf\t",def_mean,def_fixed_mean,def_isolated_mean,def_cluster_mean,def_effective_surface_mean);
        fprintf(f,"%u\n",iter_mean);
        fclose(f);
        printf("\n");
    }
    return 0;
}
Beispiel #11
0
static game_state *execute_move(game_state *from, char *move)
{
    game_state *ret = dup_game(from);
    int gx = -1, gy = -1, rangeno = -1;

    if (ret->justwrong) {
	int i;
	ret->justwrong = FALSE;
	for (i = 0; i < ret->nlasers; i++)
	    if (ret->exits[i] != LASER_EMPTY)
		ret->exits[i] &= ~(LASER_OMITTED | LASER_WRONG);
    }

    if (!strcmp(move, "S")) {
        check_guesses(ret, FALSE);
        return ret;
    }

    if (from->reveal) goto badmove;
    if (!*move) goto badmove;

    switch (move[0]) {
    case 'T':
        sscanf(move+1, "%d,%d", &gx, &gy);
        if (gx < 1 || gy < 1 || gx > ret->w || gy > ret->h)
            goto badmove;
        if (GRID(ret, gx, gy) & BALL_GUESS) {
            ret->nguesses--;
            GRID(ret, gx, gy) &= ~BALL_GUESS;
        } else {
            ret->nguesses++;
            GRID(ret, gx, gy) |= BALL_GUESS;
        }
        break;

    case 'F':
        sscanf(move+1, "%d", &rangeno);
        if (ret->exits[rangeno] != LASER_EMPTY)
            goto badmove;
        if (!RANGECHECK(ret, rangeno))
            goto badmove;
        fire_laser(ret, rangeno);
        break;

    case 'R':
        if (ret->nguesses < ret->minballs ||
            ret->nguesses > ret->maxballs)
            goto badmove;
        check_guesses(ret, TRUE);
        break;

    case 'L':
        {
            int lcount = 0;
            if (strlen(move) < 2) goto badmove;
            switch (move[1]) {
            case 'B':
                sscanf(move+2, "%d,%d", &gx, &gy);
                if (gx < 1 || gy < 1 || gx > ret->w || gy > ret->h)
                    goto badmove;
                GRID(ret, gx, gy) ^= BALL_LOCK;
                break;

#define COUNTLOCK do { if (GRID(ret, gx, gy) & BALL_LOCK) lcount++; } while (0)
#define SETLOCKIF(c) do {                                       \
    if (lcount > (c)) GRID(ret, gx, gy) &= ~BALL_LOCK;          \
    else              GRID(ret, gx, gy) |= BALL_LOCK;           \
} while(0)

            case 'C':
                sscanf(move+2, "%d", &gx);
                if (gx < 1 || gx > ret->w) goto badmove;
                for (gy = 1; gy <= ret->h; gy++) { COUNTLOCK; }
                for (gy = 1; gy <= ret->h; gy++) { SETLOCKIF(ret->h/2); }
                break;

            case 'R':
                sscanf(move+2, "%d", &gy);
                if (gy < 1 || gy > ret->h) goto badmove;
                for (gx = 1; gx <= ret->w; gx++) { COUNTLOCK; }
                for (gx = 1; gx <= ret->w; gx++) { SETLOCKIF(ret->w/2); }
                break;

#undef COUNTLOCK
#undef SETLOCKIF

            default:
                goto badmove;
            }
        }
        break;

    default:
        goto badmove;
    }

    return ret;

badmove:
    free_game(ret);
    return NULL;
}
Beispiel #12
0
/* Checks that the guessed balls in the state match up with the real balls
 * for all possible lasers (i.e. not just the ones that the player might
 * have already guessed). This is required because any layout with >4 balls
 * might have multiple valid solutions. Returns non-zero for a 'correct'
 * (i.e. consistent) layout. */
static int check_guesses(game_state *state, int cagey)
{
    game_state *solution, *guesses;
    int i, x, y, n, unused, tmp;
    int ret = 0;

    if (cagey) {
	/*
	 * First, check that each laser the player has already
	 * fired is consistent with the layout. If not, show them
	 * one error they've made and reveal no further
	 * information.
	 *
	 * Failing that, check to see whether the player would have
	 * been able to fire any laser which distinguished the real
	 * solution from their guess. If so, show them one such
	 * laser and reveal no further information.
	 */
	guesses = dup_game(state);
	/* clear out BALL_CORRECT on guess, make BALL_GUESS BALL_CORRECT. */
	for (x = 1; x <= state->w; x++) {
	    for (y = 1; y <= state->h; y++) {
		GRID(guesses, x, y) &= ~BALL_CORRECT;
		if (GRID(guesses, x, y) & BALL_GUESS)
		    GRID(guesses, x, y) |= BALL_CORRECT;
	    }
	}
	n = 0;
	for (i = 0; i < guesses->nlasers; i++) {
	    if (guesses->exits[i] != LASER_EMPTY &&
		guesses->exits[i] != laser_exit(guesses, i))
		n++;
	}
	if (n) {
	    /*
	     * At least one of the player's existing lasers
	     * contradicts their ball placement. Pick a random one,
	     * highlight it, and return.
	     *
	     * A temporary random state is created from the current
	     * grid, so that repeating the same marking will give
	     * the same answer instead of a different one.
	     */
	    random_state *rs = random_new((char *)guesses->grid,
					  (state->w+2)*(state->h+2) *
					  sizeof(unsigned int));
	    n = random_upto(rs, n);
	    random_free(rs);
	    for (i = 0; i < guesses->nlasers; i++) {
		if (guesses->exits[i] != LASER_EMPTY &&
		    guesses->exits[i] != laser_exit(guesses, i) &&
		    n-- == 0) {
		    state->exits[i] |= LASER_WRONG;
		    tmp = laser_exit(state, i);
		    if (RANGECHECK(state, tmp))
			state->exits[tmp] |= LASER_WRONG;
		    state->justwrong = TRUE;
		    free_game(guesses);
		    return 0;
		}
	    }
	}
	n = 0;
	for (i = 0; i < guesses->nlasers; i++) {
	    if (guesses->exits[i] == LASER_EMPTY &&
		laser_exit(state, i) != laser_exit(guesses, i))
		n++;
	}
	if (n) {
	    /*
	     * At least one of the player's unfired lasers would
	     * demonstrate their ball placement to be wrong. Pick a
	     * random one, highlight it, and return.
	     *
	     * A temporary random state is created from the current
	     * grid, so that repeating the same marking will give
	     * the same answer instead of a different one.
	     */
	    random_state *rs = random_new((char *)guesses->grid,
					  (state->w+2)*(state->h+2) *
					  sizeof(unsigned int));
	    n = random_upto(rs, n);
	    random_free(rs);
	    for (i = 0; i < guesses->nlasers; i++) {
		if (guesses->exits[i] == LASER_EMPTY &&
		    laser_exit(state, i) != laser_exit(guesses, i) &&
		    n-- == 0) {
		    fire_laser(state, i);
		    state->exits[i] |= LASER_OMITTED;
		    tmp = laser_exit(state, i);
		    if (RANGECHECK(state, tmp))
			state->exits[tmp] |= LASER_OMITTED;
		    state->justwrong = TRUE;
		    free_game(guesses);
		    return 0;
		}
	    }
	}
	free_game(guesses);
    }

    /* duplicate the state (to solution) */
    solution = dup_game(state);

    /* clear out the lasers of solution */
    for (i = 0; i < solution->nlasers; i++) {
        tmp = range2grid(solution, i, &x, &y, &unused);
        assert(tmp);
        GRID(solution, x, y) = 0;
        solution->exits[i] = LASER_EMPTY;
    }

    /* duplicate solution to guess. */
    guesses = dup_game(solution);

    /* clear out BALL_CORRECT on guess, make BALL_GUESS BALL_CORRECT. */
    for (x = 1; x <= state->w; x++) {
        for (y = 1; y <= state->h; y++) {
            GRID(guesses, x, y) &= ~BALL_CORRECT;
            if (GRID(guesses, x, y) & BALL_GUESS)
                GRID(guesses, x, y) |= BALL_CORRECT;
        }
    }

    /* for each laser (on both game_states), fire it if it hasn't been fired.
     * If one has been fired (or received a hit) and another hasn't, we know
     * the ball layouts didn't match and can short-circuit return. */
    for (i = 0; i < solution->nlasers; i++) {
        if (solution->exits[i] == LASER_EMPTY)
            fire_laser(solution, i);
        if (guesses->exits[i] == LASER_EMPTY)
            fire_laser(guesses, i);
    }

    /* check each game_state's laser against the other; if any differ, return 0 */
    ret = 1;
    for (i = 0; i < solution->nlasers; i++) {
        tmp = range2grid(solution, i, &x, &y, &unused);
        assert(tmp);

        if (solution->exits[i] != guesses->exits[i]) {
            /* If the original state didn't have this shot fired,
             * and it would be wrong between the guess and the solution,
             * add it. */
            if (state->exits[i] == LASER_EMPTY) {
                state->exits[i] = solution->exits[i];
                if (state->exits[i] == LASER_REFLECT ||
                    state->exits[i] == LASER_HIT)
                    GRID(state, x, y) = state->exits[i];
                else {
                    /* add a new shot, incrementing state's laser count. */
                    int ex, ey, newno = state->laserno++;
                    tmp = range2grid(state, state->exits[i], &ex, &ey, &unused);
                    assert(tmp);
                    GRID(state, x, y) = newno;
                    GRID(state, ex, ey) = newno;
                }
		state->exits[i] |= LASER_OMITTED;
            } else {
		state->exits[i] |= LASER_WRONG;
	    }
            ret = 0;
        }
    }
    if (ret == 0 ||
	state->nguesses < state->minballs ||
	state->nguesses > state->maxballs) goto done;

    /* fix up original state so the 'correct' balls end up matching the guesses,
     * as we've just proved that they were equivalent. */
    for (x = 1; x <= state->w; x++) {
        for (y = 1; y <= state->h; y++) {
            if (GRID(state, x, y) & BALL_GUESS)
                GRID(state, x, y) |= BALL_CORRECT;
            else
                GRID(state, x, y) &= ~BALL_CORRECT;
        }
    }

done:
    /* fill in nright and nwrong. */
    state->nright = state->nwrong = state->nmissed = 0;
    for (x = 1; x <= state->w; x++) {
        for (y = 1; y <= state->h; y++) {
            int bs = GRID(state, x, y) & (BALL_GUESS | BALL_CORRECT);
            if (bs == (BALL_GUESS | BALL_CORRECT))
                state->nright++;
            else if (bs == BALL_GUESS)
                state->nwrong++;
            else if (bs == BALL_CORRECT)
                state->nmissed++;
        }
    }
    free_game(solution);
    free_game(guesses);
    state->reveal = 1;
    return ret;
}
Beispiel #13
0
void __fastcall run_game_loop(int uMsg)
{
	//int v3; // eax
	bool v5; // zf
	//int v6; // eax
	signed int v7; // [esp+8h] [ebp-24h]
	LRESULT (__stdcall *saveProc)(HWND, UINT, WPARAM, LPARAM); // [esp+Ch] [ebp-20h]
	struct tagMSG msg; // [esp+10h] [ebp-1Ch]

	nthread_ignore_mutex(1);
	start_game(uMsg);
	saveProc = SetWindowProc(GM_Game);
	control_update_life_mana();
	msg_process_net_packets();
	gbRunGame = 1;
	gbProcessPlayers = 1;
	gbRunGameResult = 1;
	drawpanflag = 255;
	DrawAndBlit();
	PaletteFadeIn(8);
	drawpanflag = 255;
	gbGameLoopStartup = 1;
	nthread_ignore_mutex(0);
	while ( gbRunGame )
	{
		diablo_color_cyc_logic();
		if ( PeekMessageA(&msg, NULL, 0, 0, PM_NOREMOVE) )
		{
			SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_ABOVE_NORMAL);
			while ( PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE) )
			{
				if ( msg.message == WM_QUIT )
				{
					gbRunGameResult = 0;
					gbRunGame = 0;
					break;
				}
				TranslateMessage(&msg);
				DispatchMessageA(&msg);
			}
			if ( !gbRunGame || (v7 = 1, !nthread_has_500ms_passed()) )
				v7 = 0;
			SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_NORMAL);
			v5 = v7 == 0;
		}
		else
		{
			//_LOBYTE(v6) = nthread_has_500ms_passed();
			v5 = nthread_has_500ms_passed() == 0;
		}
		if ( !v5 )
		{
			multi_process_network_packets();
			game_loop(gbGameLoopStartup);
			msgcmd_send_chat();
			gbGameLoopStartup = 0;
			DrawAndBlit();
		}
#ifdef SLEEP
		Sleep(1);
#endif
	}
	if ( (unsigned char)gbMaxPlayers > 1u )
		pfile_write_hero();
	pfile_flush_W();
	PaletteFadeOut(8);
	SetCursor(0);
	ClearScreenBuffer();
	drawpanflag = 255;
	scrollrt_draw_game_screen(1);
	SetWindowProc(saveProc);
	free_game();
	if ( cineflag )
	{
		cineflag = 0;
		DoEnding();
	}
}
Beispiel #14
0
///////////////////////////////////
// MAIN (only for internal test) //
///////////////////////////////////
int
main ()
{
  // Valgrind run
  init_chess_library ();
  int i, from, to;

  for (i = 0; i < 1000; i++)
    {
      Game *g = init_game ();
      Board *board;
      char *fen;

      // 1. e4 a6 2. Bc4 a5 3. Qh5 a4 4. Qxf7#
      board = current_board (g);
      get_coord (board, 'P', "e", "e4", 0, &from, &to);
      pseudo_legal_move (board, from, to);
      apply_move (g, from, to, 0);
      fen = to_fen (board);
      free (fen);

      board = current_board (g);
      get_coord (board, 'P', "a", "a6", 0, &from, &to);
      pseudo_legal_move (board, from, to);
      apply_move (g, from, to, 0);
      fen = to_fen (current_board (g));
      free (fen);

      board = current_board (g);
      get_coord (board, 'B', "", "c4", 0, &from, &to);
      pseudo_legal_move (board, from, to);
      apply_move (g, from, to, 0);
      fen = to_fen (current_board (g));
      free (fen);

      board = current_board (g);
      get_coord (board, 'P', "a", "a5", 0, &from, &to);
      pseudo_legal_move (board, from, to);
      apply_move (g, from, to, 0);
      fen = to_fen (current_board (g));
      free (fen);

      board = current_board (g);
      get_coord (board, 'Q', "", "h5", 0, &from, &to);
      pseudo_legal_move (board, from, to);
      apply_move (g, from, to, 0);
      fen = to_fen (current_board (g));
      free (fen);

      board = current_board (g);
      get_coord (board, 'P', "a", "a4", 0, &from, &to);
      pseudo_legal_move (board, from, to);
      apply_move (g, from, to, 0);
      fen = to_fen (current_board (g));
      free (fen);

      board = current_board (g);
      get_coord (board, 'Q', "", "f7", 0, &from, &to);
      pseudo_legal_move (board, from, to);
      apply_move (g, from, to, 0);
      fen = to_fen (current_board (g));
      free (fen);

      free_game (g);
    }
  return 0;
}