Millebornes Game (#2598)(an instance of generic room made by Sick)     An incomplete Millebornes game. Go to location of this object, Tower Chamber. VERB SOURCE CODE: join:
"Usage: join";
"Join the game before it has been started.";
"Once the game is in progress, a new player may join only if an existing player abandons
eir hand.";
if (caller != player)
caller:tell(E_PERM);
return E_PERM;
elseif (player in this.players)
player:tell("You're already playing, silly.");
elseif (this.in_progress)
if (i = $nothing in this.players)
"... take over an abandoned hand";
this:announce_all(player.name, " joins the game, and takes over an abandoned
hand.");
this.players[i] = player;
if (i = $set_utils:count(this.players, $nothing))
this:announce_all("However, the game cannot resume until the ", i, "
remaining abandoned ", (i == 1) ? "hand is" | "hands are", " taken.");
this:announce_all("If you cannot find enough players, you'll have to
`end' the game.");
endif
else
player:tell("There is already a game in progress. You'll have to wait for
the next game.");
endif
elseif (length(this.players) >= 4)
player:tell("There cannot be more than 4 players, sorry.");
this:announce(player.name, " tries to join the game, but there are already four
players.");
else
this:announce_all(player.name, " joins the game.");
if ((pnum = length(this.players = setadd(this.players, player))) == 1)
this:announce_all("At least one other player is needed to start the game.");
elseif (pnum == 2)
this:announce_all("Someone can `start' the game now, or find two other players.");
elseif (pnum == 3)
this:announce_all("You need one more or one less player before you can start
the game.");
elseif (pnum == 4)
this:announce_all("There is no room for more players. Someone should `start'
the game now.");
endif
endif
.
quit:
"Usage: quit";
"Quit the game before it has been started.";
"Once the game is in progress, a player may quit and abandon eir hand. A new player
must then join to take control of the abandoned hand.";
"If a hand is abandoned and a new player does not take over, someone must 'end' the
game.";
if (caller != player)
caller:tell(E_PERM);
return E_PERM;
elseif (!(idx = player in this.players))
player:tell("You aren't playing, silly.");
elseif (this.in_progress)
"... abandon hand";
this.players[idx] = $nothing;
this:announce_all(player.name, " leaves the game. Someone must `join' and take
over ", player.name, "'s hand before the game may continue.");
else
"... quit before started";
this:announce_all(player.name, " decides not to play.");
if ((pnum = length(this.players = setremove(this.players, player))) == 1)
this:announce_all("At least one other player is needed to start the game.");
elseif (pnum == 2)
this:announce_all("Someone can `start' the game now, or find two other players.");
elseif (pnum == 3)
this:announce_all("You need one more or one less player before you can start
the game.");
endif
endif
.
start:
"Usage: start";
"Start the game once two or four players have joined.";
if (caller != player)
caller:tell(E_PERM);
return E_PERM;
elseif (!(player in this.players))
player:tell("You can only start the game if you are playing.");
elseif ((pnum = length(this.players)) == 1)
player:tell("You need at least one more player before you can start the game.");
elseif (pnum == 3)
player:tell("You need one more or one less player before you can start the game.");
else
this:announce_all(player.name, " starts the game.");
this:start_game();
endif
.
play: "Usage: play discard: "Usage: discard start_game:
"Syntax: start_game()";
"Initialize game properties, deal hands, select first player.";
if (caller != this)
return E_PERM;
endif
pnum = length(players = this.players);
"... initialize properties";
this.in_progress = 1;
this.hands = this.safeties = this.miles = $list_utils:make(pnum, {});
this.coups = this.limits = $list_utils:make(pnum, 0);
this.actions = $list_utils:make(pnum, "Stop");
this.current_turn = $nothing;
this.discarded = {};
this:announce_all("Shuffling the deck...");
this.remaining = this.unplayed = this.db:random_deck();
this:announce_all("Dealing hands...");
for x in [1..6]
for who in (this.players)
this:deal_card(who);
endfor
endfor
who = players[random(pnum)];
this:announce_all(who.name, " will lead the game.");
this:set_turn(who);
.
set_turn:
"Syntax: set_turn(player);";
"Deal the player a card and make it eir turn.";
if (caller != this)
return E_PERM;
endif
this.current_turn = who = args[1];
this:announce_all("It is now ", who.name, "'s turn.");
this:deal_card(who);
.
do_discard:
"Syntax: do_discard(player, card)";
"Discard the card from the player's hand.";
if (caller != this)
return E_PERM;
endif
widx = (who = args[1]) in this.players;
this:announce_all(who.name, " discards ", this.db:card_title(card = args[2]), ".");
this.hands[widx] = setremove(this.hands[widx], card);
this.discarded = listappend(this.discarded, card);
this.unplayed = setremove(this.unplayed, card);
.
do_play:
"Syntax: do_play(player, card, victim)";
"Play card from player's hand. If hazard, play on victim.";
if (caller != this)
return E_PERM;
endif
widx = (who = args[1]) in this.players;
card = args[2];
vidx = (victim = args[3]) in this.players;
if (card in {"25 Miles", "50 Miles", "75 Miles", "100 Miles", "200 Miles"})
this.miles[widx] = listappend(this.miles[widx], card);
this:announce_all(who.name, " plays ", this.db:card_title(card), " for a total
of ", this:total_miles(who), ".");
elseif (card == "End of Limit")
this.limits[widx] = 0;
this:announce_all(who.name, " plays ", this.db:card_title(card), ".");
elseif (card in {"Gasoline", "Spare Tire", "Repairs", "Go"})
this.actions[widx] = ((card == "Go") || ("Right of Way" in this.safeties[widx]))
? "Go" | "Stop";
this:announce_all(who.name, " plays ", this.db:card_title(card), ".");
elseif (card in {"Extra Tank", "Puncture Proof", "Driving Ace", "Right of Way"})
if (coup = (card in this.hands[widx]) != 7)
this.coups[widx] = this.coups[widx] + 1;
endif
this.safeties[widx] = listappend(this.safeties[widx], card);
this.actions[widx] = (coup || ("Right of Way" in this.safeties[widx])) ? "Go"
| "Stop";
this:announce(coup ? "* COUP FOURRE! * " | "", who.name, " plays ", this.db:card_title(card),
"!");
elseif (card == "Speed Limit")
this.limits[vidx] = 1;
this:announce_all(who.name, " plays ", this.db:card_title(card), " on ", victim.name,
".");
elseif (card in {"Out of Gas", "Flat Tire", "Accident", "Stop"})
this.actions[vidx] = card;
this:announce_all(who.name, " plays ", this.db:card_title(card), " on ", victim.name);
endif
this.hands[widx] = setremove(this.hands[widx], card);
this.unplayed = setremove(this.unplayed, card);
.
can_play:
"Syntax: can_play(player, card, victim) => 0 | 1";
"Can the player play the card (if hazard, on victim)?";
if (caller != this)
return E_PERM;
endif
widx = (who = args[1]) in this.players;
card = args[2];
vidx = (victim = args[3]) in this.players;
wact = this.actions[widx];
vact = this.actions[vidx];
if (card in {"25 Miles", "50 Miles", "75 Miles", "100 Miles", "200 Miles"})
if (wact != "Go")
who:tell("You must remedy your \"", wact, "\" before playing miles.");
elseif ((this:total_miles(who) + this:num_miles(card)) > 700)
who:tell("That would give you more than 700 miles!");
elseif ((card == "200 Miles") && ($list_utils:count(this.miles[widx], "200 Miles")
== 2))
who:tell("You can only play two 200 Miles cards.");
else
return 1;
endif
elseif (card == "End of Limit")
if (this.limits[widx])
return 1;
else
who:tell("You don't have a Speed Limit!");
endif
elseif (i = card in {"Gasoline", "Spare Tire", "Repairs", "Go"})
hazards = {"Out of Gas", "Flat Tire", "Accident", "Stop"};
if (this.actions[widx] == hazards[i])
return 1;
else
who:tell("You don't have a \"", hazards[i], "\" to remedy!");
endif
elseif (card in {"Extra Tank", "Puncture Proof", "Driving Ace", "Right of Way"})
return 1;
elseif (!valid(victim))
who:tell("You must specify a victim for that card!");
elseif (card == "Speed Limit")
if (this.limits[vidx])
who:tell(victim.name, " already has a Speed Limit!");
elseif ("Right of Way" in this.safeties[vidx])
who:tell(victim.name, " has played the Right of Way!");
else
return 1;
endif
elseif (i = card in {"Out of Gas", "Flat Tire", "Accident", "Stop"})
safeties = {"Extra Tank", "Puncture Proof", "Driving Ace", "Right of Way"};
if (safeties[i] in this.safeties[vidx])
who:tell(victim.name, " has played the ", safeties[i], " safety!");
elseif (vact != "Go")
who:tell(victim.name, " already has a ", vact, "!");
else
return 1;
endif
else
who:tell("\"", card, "\"?! How did you get that?");
endif
.
total_miles:
total = 0;
for m in (this.miles[args[1] in this.players])
total = total + this:num_miles(m);
endfor
return total;
.
num_miles: miles = args[1]; return tonum(miles[1..index(miles, " ") - 1]); . deal_card:
"Syntax: deal_card(player)";
"Deals the player a random card from the deck.";
if (caller != this)
return E_PERM;
endif
widx = (who = args[1]) in this.players;
card = this.remaining[i = random(length(this.remaining))];
this.remaining = listdelete(this.remaining, i);
this.hands[widx] = listappend(this.hands[widx], card);
this:announce_all_but({who}, who.name, " is dealt a card from the deck.");
who:tell("You are dealt ", this.db:card_title(card), ".");
.
next_turn:
"Syntax: next_turn()";
"Become the next player's turn.";
if (caller != this)
return E_PERM;
endif
if ((i = this.current_turn in this.players) == length(this.players))
this:set_turn(this.players[1]);
else
this:set_turn(this.players[i + 1]);
endif
.
board_description:
if (this.in_progress)
text = {""};
su = $string_utils;
for i in [1..length(this.players)]
p = this.players[i];
if (mlist = this.miles[i])
total = 0;
miles = "";
for m in (mlist)
total = total + (n = this:num_miles(m));
miles = tostr(miles, "+", n);
endfor
miles[1..1] = "";
miles = tostr(su:right(total, 3), " (", miles, ")");
else
miles = " 0";
endif
text = {@text, tostr(su:right((p == player) ? "YOU" | (valid(p) ? p.name
| "
show_hand:
if (this.in_progress && (i = player in this.players))
dealt = 0;
if (length(hand = this.hands[i]) > 6)
dealt = hand[7];
hand[7..7] = {};
endif
player:tell("Your hand: ", $string_utils:from_list($list_utils:sort(hand), ",
"));
dealt && player:tell(" Dealt: ", dealt);
endif
.
look_self:
player:tell(this:title());
if (!(args && args[1]))
player:tell_lines(this:description());
endif
this:show_hand();
player:tell("");
this:tell_contents(setremove(this:contents(), player), this.ctype);
this:tell_exits();
.
description:
"... get .description and convert to {list}";
(typeof(desc = pass(@args)) == LIST) || (desc = {desc});
"... append game board";
desc = {@desc, @this:board_description()};
return desc;
.
PROPERTY DATA:       in_progress       players       remaining       discarded       unplayed       hands       safeties       miles       coups       limits       actions       current_turn       db |