33 if ( e.classname ==
"minigame_board_piece" && e.netname == tile )
54 if ( number == letter )
60 if ( number == 2-letter )
76 return 0 <= number && number < TTT_NUM_CNT && 0 <= letter && letter <
TTT_LET_CNT;
82 if ( minigame.minigame_flags & TTT_TURN_PLACE )
83 if ( pos && player.team == (minigame.minigame_flags & TTT_TURN_TEAM) )
89 piece.team = player.team;
93 minigame.ttt_npieces++;
97 player.minigame_flags++;
99 minigame.minigame_flags = TTT_TURN_WIN | player.team;
101 else if ( minigame.ttt_npieces >= (TTT_LET_CNT * TTT_NUM_CNT) )
104 minigame.minigame_flags = TTT_TURN_PLACE | minigame.ttt_nexteam;
114 if ( minigame.minigame_flags & (TTT_TURN_WIN|TTT_TURN_DRAW) )
116 minigame.minigame_flags = TTT_TURN_NEXT | player.team;
119 else if ( (minigame.minigame_flags & TTT_TURN_NEXT) &&
120 !( minigame.minigame_flags & player.team ) )
123 minigame.minigame_flags = TTT_TURN_PLACE | minigame.ttt_nexteam;
125 minigame.ttt_npieces = 0;
128 if ( e.classname ==
"minigame_board_piece" )
137 int ttt_server_event(
entity minigame,
string event, ...)
150 if(e.classname ==
"minigame_board_piece")
162 if ( (minigame.ttt_ai) && pl_num > 0 )
169 if(minigame.minigame_players)
208 if ( sent.classname ==
"minigame_player" && (sf & TTT_SF_PLAYERSCORE ) )
210 WriteByte(MSG_ENTITY,sent.minigame_flags);
212 else if ( sent.classname ==
"minigame" && (sf & TTT_SF_SINGLEPLAYER) )
236 ttt_boardsize = mySize;
256 if ( e.classname ==
"minigame_board_piece" )
262 if ( !e.ttt_checkwin )
265 float icon_color = 1;
266 if ( e.ttt_checkwin == -1 )
268 else if ( e.ttt_checkwin == 1 )
295 ts_y = ( mySize_y - 2*player_fontsize_y ) / 2;
298 vector tile_size =
'48 48 0';
303 if ( e.classname ==
"minigame_player" && e.team != TTT_SPECTATOR_TEAM )
307 mypos_y += player_fontsize_y + ts_y;
309 (e.minigame_playerslot ? entcs_GetName(e.minigame_playerslot-1) : _(
"AI")),
312 mypos_y += player_fontsize_y;
317 mypos_x += tile_size_x;
326 string ttt_turn_to_string(
int turnflags)
329 return _(
"You are spectating");
331 if ( turnflags & TTT_TURN_DRAW )
334 if ( turnflags & TTT_TURN_WIN )
339 return strcat(_(
"You lost the game!"),
"\n", _(
"Select \"^1Next Match^7\" on the menu for a rematch!"));
340 return strcat(_(
"You win!"),
"\n", _(
"Select \"^1Next Match^7\" on the menu to start a new match!"));
343 if ( turnflags & TTT_TURN_NEXT )
346 return _(
"Select \"^1Next Match^7\" on the menu to start a new match!");
347 return _(
"Wait for your opponent to confirm the rematch");
351 return _(
"Wait for your opponent to make their move");
353 if ( turnflags & TTT_TURN_PLACE )
354 return _(
"Click on the game board to place your piece");
359 const int TTT_AI_POSFLAG_A1 = 0x0001;
360 const int TTT_AI_POSFLAG_A2 = 0x0002;
361 const int TTT_AI_POSFLAG_A3 = 0x0004;
362 const int TTT_AI_POSFLAG_B1 = 0x0008;
363 const int TTT_AI_POSFLAG_B2 = 0x0010;
364 const int TTT_AI_POSFLAG_B3 = 0x0020;
365 const int TTT_AI_POSFLAG_C1 = 0x0040;
366 const int TTT_AI_POSFLAG_C2 = 0x0080;
367 const int TTT_AI_POSFLAG_C3 = 0x0100;
370 string ttt_ai_piece_flag2pos(
int pieceflag)
374 case TTT_AI_POSFLAG_A1:
376 case TTT_AI_POSFLAG_A2:
378 case TTT_AI_POSFLAG_A3:
381 case TTT_AI_POSFLAG_B1:
383 case TTT_AI_POSFLAG_B2:
385 case TTT_AI_POSFLAG_B3:
388 case TTT_AI_POSFLAG_C1:
390 case TTT_AI_POSFLAG_C2:
392 case TTT_AI_POSFLAG_C3:
400 bool ttt_ai_checkmask(
int piecemask,
int checkflags)
402 return checkflags && (piecemask & checkflags) == checkflags;
406 int ttt_ai_1of3(
int piecemask,
int flag1,
int flag2,
int flag3)
408 if ( ttt_ai_checkmask(piecemask,flag1|flag2|flag3) )
411 if ( ttt_ai_checkmask(piecemask,flag1|flag2) )
414 if ( ttt_ai_checkmask(piecemask,flag3|flag2) )
417 if ( ttt_ai_checkmask(piecemask,flag3|flag1) )
424 int ttt_ai_random(
int piecemask)
433 for (
int i = 0; i < 9; i++ )
440 LOG_TRACE(sprintf(
"TTT AI: selected %x from %x",
446 int ttt_ai_block3 (
int piecemask,
int piecemask_free )
450 r |= ttt_ai_1of3(piecemask,TTT_AI_POSFLAG_A1,TTT_AI_POSFLAG_A2,TTT_AI_POSFLAG_A3);
451 r |= ttt_ai_1of3(piecemask,TTT_AI_POSFLAG_B1,TTT_AI_POSFLAG_B2,TTT_AI_POSFLAG_B3);
452 r |= ttt_ai_1of3(piecemask,TTT_AI_POSFLAG_C1,TTT_AI_POSFLAG_C2,TTT_AI_POSFLAG_C3);
453 r |= ttt_ai_1of3(piecemask,TTT_AI_POSFLAG_A1,TTT_AI_POSFLAG_B1,TTT_AI_POSFLAG_C1);
454 r |= ttt_ai_1of3(piecemask,TTT_AI_POSFLAG_A2,TTT_AI_POSFLAG_B2,TTT_AI_POSFLAG_C2);
455 r |= ttt_ai_1of3(piecemask,TTT_AI_POSFLAG_A3,TTT_AI_POSFLAG_B3,TTT_AI_POSFLAG_C3);
456 r |= ttt_ai_1of3(piecemask,TTT_AI_POSFLAG_A1,TTT_AI_POSFLAG_B2,TTT_AI_POSFLAG_C3);
457 r |= ttt_ai_1of3(piecemask,TTT_AI_POSFLAG_A3,TTT_AI_POSFLAG_B2,TTT_AI_POSFLAG_C1);
458 LOG_TRACE(sprintf(
"TTT AI: possible 3 in a rows in %x: %x (%x)",piecemask,r, r&piecemask_free));
460 return ttt_ai_random(r);
467 string ttt_ai_choose_simple(
int piecemask_self,
int piecemask_opponent,
int piecemask_free )
471 LOG_TRACE(
"TTT AI: checking winning move");
472 if (( move = ttt_ai_block3(piecemask_self,piecemask_free) ))
473 return ttt_ai_piece_flag2pos(move);
475 LOG_TRACE(
"TTT AI: checking opponent's winning move");
476 if (( move = ttt_ai_block3(piecemask_opponent,piecemask_free) ))
477 return ttt_ai_piece_flag2pos(move);
480 return ttt_ai_piece_flag2pos(ttt_ai_random(piecemask_free));
484 void ttt_aimove(
entity minigame)
486 if ( minigame.minigame_flags == (TTT_TURN_PLACE|minigame.ttt_ai) )
490 if ( aiplayer.classname ==
"minigame_player" && !aiplayer.minigame_playerslot )
504 int piecemask_self = 0;
505 int piecemask_opponent = 0;
506 int piecemask_free = 0;
509 for (
int i = 0; i < 3; i++ )
511 for (
int j = 0; j < 3; j++ )
517 if ( piece.team == aiplayer.team )
518 piecemask_self |= pieceflag;
520 piecemask_opponent |= pieceflag;
523 piecemask_free |= pieceflag;
529 LOG_TRACE(sprintf(
"TTT AI: self: %x opponent: %x free: %x",
530 piecemask_self, piecemask_opponent, piecemask_free));
531 pos = ttt_ai_choose_simple(piecemask_self, piecemask_opponent, piecemask_free);
538 strcpy(minigame.message, ttt_turn_to_string(minigame.minigame_flags));
542 void ttt_make_move(
entity minigame)
544 if ( minigame.minigame_flags == (TTT_TURN_PLACE|
minigame_self.team) )
546 if ( minigame.ttt_ai )
549 ttt_aimove(minigame);
556 void ttt_set_curr_pos(
string s)
565 int ttt_client_event(
entity minigame,
string event, ...)
571 ttt_set_curr_pos(
"");
572 strcpy(minigame.message, ttt_turn_to_string(minigame.minigame_flags));
583 bool event_blocked = ((
event ==
"key_released")
584 || ((minigame.minigame_flags & TTT_TURN_TEAM) !=
minigame_self.team));
585 if (!(minigame.minigame_flags & TTT_TURN_WIN) && !(minigame.minigame_flags &
TTT_TURN_DRAW))
587 switch ( ...(0,
int) )
593 if ( ! ttt_curr_pos )
594 ttt_set_curr_pos(
"a3");
602 if ( ! ttt_curr_pos )
603 ttt_set_curr_pos(
"c3");
611 if ( ! ttt_curr_pos )
612 ttt_set_curr_pos(
"a1");
620 if ( ! ttt_curr_pos )
621 ttt_set_curr_pos(
"a3");
630 ttt_make_move(minigame);
637 case "mouse_pressed":
641 ttt_client_event(minigame,
"mouse_moved");
642 ttt_make_move(minigame);
651 if ( minigame.minigame_flags == (TTT_TURN_PLACE|
minigame_self.team) )
654 ttt_set_curr_pos(
"");
658 case "network_receive":
662 if ( sent.classname ==
"minigame" )
666 strcpy(sent.message, ttt_turn_to_string(sent.minigame_flags));
671 if ( (sf & TTT_SF_SINGLEPLAYER) )
674 bool spawnai = ai && !sent.ttt_ai;
679 entity aiplayer =
new(minigame_player);
680 aiplayer.owner = minigame;
682 aiplayer.minigame_playerslot = 0;
683 aiplayer.minigame_autoclean = 1;
684 ttt_aimove(minigame);
689 else if ( sent.classname ==
"minigame_player" && (sf & TTT_SF_PLAYERSCORE ) )
691 sent.minigame_flags = ReadByte();
704 if(...(0,
string) ==
"next")
706 if ( minigame.ttt_ai )
709 ttt_aimove(minigame);
714 else if ( ...(0,
string) ==
"singleplayer" && !minigame.ttt_ai )
int minigame_tile_number(string id)
void minigame_server_sendflags(entity ent, int mgflags)
void HUD_MinigameMenu_CustomEntry(entity parent, string menumessage, string event_arg)
void ttt_next_match(entity minigame, entity player)
#define FOREACH_MINIGAME_ENTITY(entityvar)
REGISTER_MINIGAME(ttt, _("Tic Tac Toe"))
const int TTT_SF_SINGLEPLAYER
vector minigame_hud_denormalize_size(vector v, vector pos, vector mySize)
#define minigame_hud_fitsqare(pos, mySize)
ERASEABLE void RandomSelection_Init()
entity msle_spawn(entity minigame_session, entity e)
int minigame_next_team(int curr_team, int n_teams)
vector minigame_hud_normalize(vector v, vector pos, vector mySize)
float RandomSelection_chosen_float
const int MINIG_SF_UPDATE
const int TTT_SF_PLAYERSCORE
bool ttt_valid_tile(string tile)
string minigame_tile_name(vector pos, int rows, int columns)
const float DRAWFLAG_ADDITIVE
const int MINIG_SF_CUSTOM
#define HUD_Panel_DrawBg()
void minigame_drawpic_centered(vector pos, string texture, vector sz, vector color, float thealpha, int drawflags)
string minigame_texture(string name)
void ttt_move(entity minigame, entity player, string pos)
vector minigame_tile_pos(string id, int rows, int columns)
spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 f1 s1 strcat(_("Level %s: "), "^BG%s\3\, _("^BGPress ^F2%s^BG to enter the game"))
entity ttt_find_piece(entity minig, string tile)
const int TTT_SPECTATOR_TEAM
const float DRAWFLAG_NORMAL
int minigame_tile_letter(string id)
#define minigame_cmd(...)
string minigame_tile_buildname(int letter, int number)
vector(float skel, float bonenum) _skel_get_boneabs_hidden
string minigame_relative_tile(string start_id, int dx, int dy, int rows, int columns)
#define RandomSelection_AddFloat(f, weight, priority)
int minigame_count_players(entity minigame)
vector minigame_hud_denormalize(vector v, vector pos, vector mySize)
void minigame_drawcolorcodedstring_trunc(float maxwidth, vector pos, string text, vector fontsize, float theAlpha, int drawflags)
void minigame_hud_simpleboard(vector pos, vector mySize, string board_texture)
vector minigame_drawstring_wrapped(float maxwidth, vector pos, string text, vector fontsize, vector color, float theAlpha, int drawflags, float align)
bool ttt_winning_piece(entity piece)