33 if ( e.classname ==
"minigame_board_piece" && e.netname == tile )
83 if ( pos && player.team == (minigame.minigame_flags &
TTT_TURN_TEAM) )
89 piece.team = player.team;
93 ++minigame.ttt_npieces;
97 ++player.minigame_flags;
120 !( minigame.minigame_flags & player.team ) )
125 minigame.ttt_npieces = 0;
128 if ( e.classname ==
"minigame_board_piece" )
133 if (e.minigame_autoclean)
156 if(e.classname ==
"minigame_board_piece")
168 if ( (minigame.ttt_ai) && pl_num > 0 )
175 if(minigame.minigame_players)
242 ttt_boardsize = mySize;
262 if ( e.classname ==
"minigame_board_piece" )
268 if ( !e.ttt_checkwin )
271 float icon_color = 1;
272 if ( e.ttt_checkwin == -1 )
274 else if ( e.ttt_checkwin == 1 )
302 ts_y = ( mySize_y - 2*player_fontsize_y ) / 2;
305 vector tile_size =
'48 48 0';
314 mypos_y += player_fontsize_y + ts_y;
316 (e.minigame_playerslot ?
entcs_GetName(e.minigame_playerslot-1) : _(
"AI")),
319 mypos_y += player_fontsize_y;
324 mypos_x += tile_size_x;
333string ttt_turn_to_string(
int turnflags)
336 return _(
"You are spectating");
346 return strcat(_(
"You lost the game!"),
"\n", _(
"Select \"^1Next Match^7\" on the menu for a rematch!"));
347 return strcat(_(
"You win!"),
"\n", _(
"Select \"^1Next Match^7\" on the menu to start a new match!"));
353 return _(
"Select \"^1Next Match^7\" on the menu to start a new match!");
354 return _(
"Wait for your opponent to confirm the rematch");
358 return _(
"Wait for your opponent to make their move");
361 return _(
"Click on the game board to place your piece");
366const int TTT_AI_POSFLAG_A1 = 0x0001;
367const int TTT_AI_POSFLAG_A2 = 0x0002;
368const int TTT_AI_POSFLAG_A3 = 0x0004;
369const int TTT_AI_POSFLAG_B1 = 0x0008;
370const int TTT_AI_POSFLAG_B2 = 0x0010;
371const int TTT_AI_POSFLAG_B3 = 0x0020;
372const int TTT_AI_POSFLAG_C1 = 0x0040;
373const int TTT_AI_POSFLAG_C2 = 0x0080;
374const int TTT_AI_POSFLAG_C3 = 0x0100;
377string ttt_ai_piece_flag2pos(
int pieceflag)
381 case TTT_AI_POSFLAG_A1:
383 case TTT_AI_POSFLAG_A2:
385 case TTT_AI_POSFLAG_A3:
388 case TTT_AI_POSFLAG_B1:
390 case TTT_AI_POSFLAG_B2:
392 case TTT_AI_POSFLAG_B3:
395 case TTT_AI_POSFLAG_C1:
397 case TTT_AI_POSFLAG_C2:
399 case TTT_AI_POSFLAG_C3:
407bool ttt_ai_checkmask(
int piecemask,
int checkflags)
409 return checkflags && (piecemask & checkflags) == checkflags;
413int ttt_ai_1of3(
int piecemask,
int flag1,
int flag2,
int flag3)
415 if ( ttt_ai_checkmask(piecemask,flag1|flag2|flag3) )
418 if ( ttt_ai_checkmask(piecemask,flag1|flag2) )
421 if ( ttt_ai_checkmask(piecemask,flag3|flag2) )
424 if ( ttt_ai_checkmask(piecemask,flag3|flag1) )
431int ttt_ai_random(
int piecemask)
440 for (
int i = 0; i < 9; ++i )
447 LOG_TRACE(sprintf(
"TTT AI: selected %x from %x",
453int ttt_ai_block3 (
int piecemask,
int piecemask_free )
457 r |= ttt_ai_1of3(piecemask,TTT_AI_POSFLAG_A1,TTT_AI_POSFLAG_A2,TTT_AI_POSFLAG_A3);
458 r |= ttt_ai_1of3(piecemask,TTT_AI_POSFLAG_B1,TTT_AI_POSFLAG_B2,TTT_AI_POSFLAG_B3);
459 r |= ttt_ai_1of3(piecemask,TTT_AI_POSFLAG_C1,TTT_AI_POSFLAG_C2,TTT_AI_POSFLAG_C3);
460 r |= ttt_ai_1of3(piecemask,TTT_AI_POSFLAG_A1,TTT_AI_POSFLAG_B1,TTT_AI_POSFLAG_C1);
461 r |= ttt_ai_1of3(piecemask,TTT_AI_POSFLAG_A2,TTT_AI_POSFLAG_B2,TTT_AI_POSFLAG_C2);
462 r |= ttt_ai_1of3(piecemask,TTT_AI_POSFLAG_A3,TTT_AI_POSFLAG_B3,TTT_AI_POSFLAG_C3);
463 r |= ttt_ai_1of3(piecemask,TTT_AI_POSFLAG_A1,TTT_AI_POSFLAG_B2,TTT_AI_POSFLAG_C3);
464 r |= ttt_ai_1of3(piecemask,TTT_AI_POSFLAG_A3,TTT_AI_POSFLAG_B2,TTT_AI_POSFLAG_C1);
465 LOG_TRACE(sprintf(
"TTT AI: possible 3 in a rows in %x: %x (%x)",piecemask,r, r&piecemask_free));
467 return ttt_ai_random(r);
474string ttt_ai_choose_simple(
int piecemask_self,
int piecemask_opponent,
int piecemask_free )
478 LOG_TRACE(
"TTT AI: checking winning move");
479 if (( move = ttt_ai_block3(piecemask_self,piecemask_free) ))
480 return ttt_ai_piece_flag2pos(move);
482 LOG_TRACE(
"TTT AI: checking opponent's winning move");
483 if (( move = ttt_ai_block3(piecemask_opponent,piecemask_free) ))
484 return ttt_ai_piece_flag2pos(move);
487 return ttt_ai_piece_flag2pos(ttt_ai_random(piecemask_free));
491void ttt_aimove(
entity minigame)
493 if ( minigame.minigame_flags == (
TTT_TURN_PLACE|minigame.ttt_ai) )
497 if ( aiplayer.classname ==
"minigame_player" && !aiplayer.minigame_playerslot )
511 int piecemask_self = 0;
512 int piecemask_opponent = 0;
513 int piecemask_free = 0;
516 for (
int i = 0; i < 3; ++i )
518 for (
int j = 0; j < 3; ++j )
524 if ( piece.team == aiplayer.team )
525 piecemask_self |= pieceflag;
527 piecemask_opponent |= pieceflag;
530 piecemask_free |= pieceflag;
536 LOG_TRACE(sprintf(
"TTT AI: self: %x opponent: %x free: %x",
537 piecemask_self, piecemask_opponent, piecemask_free));
538 pos = ttt_ai_choose_simple(piecemask_self, piecemask_opponent, piecemask_free);
545 strcpy(minigame.message, ttt_turn_to_string(minigame.minigame_flags));
549void ttt_make_move(
entity minigame)
553 if ( minigame.ttt_ai )
556 ttt_aimove(minigame);
563void ttt_set_curr_pos(
string s)
572int ttt_client_event(
entity minigame,
string event, ...)
578 ttt_set_curr_pos(
"");
579 strcpy(minigame.message, ttt_turn_to_string(minigame.minigame_flags));
590 bool event_blocked = ((
event ==
"key_released")
594 switch ( ...(0,
int) )
600 if ( ! ttt_curr_pos )
601 ttt_set_curr_pos(
"a3");
609 if ( ! ttt_curr_pos )
610 ttt_set_curr_pos(
"c3");
618 if ( ! ttt_curr_pos )
619 ttt_set_curr_pos(
"a1");
627 if ( ! ttt_curr_pos )
628 ttt_set_curr_pos(
"a3");
637 ttt_make_move(minigame);
644 case "mouse_pressed":
648 ttt_client_event(minigame,
"mouse_moved");
649 ttt_make_move(minigame);
661 ttt_set_curr_pos(
"");
665 case "network_receive":
669 if ( sent.classname ==
"minigame" )
673 strcpy(sent.message, ttt_turn_to_string(sent.minigame_flags));
681 bool spawnai = ai && !sent.ttt_ai;
686 entity aiplayer =
new(minigame_player);
687 aiplayer.owner = minigame;
688 aiplayer.minigame_id = minigame.minigame_id;
689 aiplayer.descriptor = minigame.descriptor;
691 aiplayer.minigame_playerslot = 0;
692 aiplayer.minigame_autoclean = 1;
693 ttt_aimove(minigame);
713 if(...(0,
string) ==
"next")
715 if ( minigame.ttt_ai )
718 ttt_aimove(minigame);
723 else if ( ...(0,
string) ==
"singleplayer" && !minigame.ttt_ai )
var entity(vector mins, vector maxs,.entity tofield) findbox_tofield_OrFallback
void minigame_drawcolorcodedstring_trunc(float maxwidth, vector pos, string text, vector fontsize, float theAlpha, int drawflags)
void minigame_show_allspecs(vector boardpos, vector boardsize)
vector minigame_drawstring_wrapped(float maxwidth, vector pos, string text, vector fontsize, vector color, float theAlpha, int drawflags, float align)
void minigame_hud_simpleboard(vector pos, vector mySize, string board_texture)
string minigame_texture(string name)
vector minigame_hud_denormalize_size(vector v, vector pos, vector mySize)
vector minigame_hud_denormalize(vector v, vector pos, vector mySize)
vector minigame_hud_normalize(vector v, vector pos, vector mySize)
void minigame_drawpic_centered(vector pos, string texture, vector sz, vector color, float thealpha, int drawflags)
#define REGISTER_MINIGAME(name, nicename)
#define minigame_hud_fitsqare(pos, mySize)
#define minigame_cmd(...)
#define FOREACH_MINIGAME_ENTITY(entityvar)
void HUD_MinigameMenu_CustomEntry(entity parent, string menumessage, string event_arg)
#define drawstring(position, text, scale, rgb, alpha, flag)
#define drawpic(position, pic, size, rgb, alpha, flag)
const float DRAWFLAG_NORMAL
const float DRAWFLAG_ADDITIVE
WriteByte(chan, ent.angles.y/DEC_FACTOR)
string entcs_GetName(int i)
#define HUD_Panel_DrawBg()
entity msle_spawn(entity minigame_session, entity e)
string minigame_relative_tile(string start_id, int dx, int dy, int rows, int columns)
void minigame_server_sendflags(entity ent, int mgflags)
int minigame_count_players(entity minigame)
int minigame_next_team(int curr_team, int n_teams)
int minigame_tile_letter(string id)
string minigame_tile_name(vector pos, int rows, int columns)
vector minigame_tile_pos(string id, int rows, int columns)
string minigame_tile_buildname(int letter, int number)
int minigame_tile_number(string id)
int minigame_id
Unique ID for the minigame session, associated with all objects currently the result of etof(minigame...
const int MINIG_SF_UPDATE
const int MINIG_SF_CUSTOM
strcat(_("^F4Countdown stopped!"), "\n^BG", _("Teams are too unbalanced."))
ERASEABLE void RandomSelection_Init()
float RandomSelection_chosen_float
#define RandomSelection_AddFloat(f, weight, priority)
const int TTT_SF_SINGLEPLAYER
const int TTT_SF_PLAYERSCORE
void ttt_move(entity minigame, entity player, string pos)
bool ttt_winning_piece(entity minigame, entity piece)
int ttt_server_event(entity minigame, string event,...)
const int TTT_SPECTATOR_TEAM
entity ttt_find_piece(entity minig, string tile)
bool ttt_valid_tile(string tile)
void ttt_next_match(entity minigame, entity player)