mirror of https://github.com/captn3m0/modernart
Implemented Nominal Turn Counting
- This ensures that every player gets atleast T|T-1 turns per round. - Comments out drawone stuff for simplicity for now - Does not consider double cards eitherpull/1/head
parent
3650ce1757
commit
da83f6eda1
|
@ -17,7 +17,7 @@ constraint forall(a in Artists) ( sum(col(awards_per_round_per_artist,a)) = 1 );
|
|||
|
||||
% awards can only be given if an artist's card was played that turn
|
||||
constraint forall(r in Rounds, a in Artists) (
|
||||
awards_per_round_per_artist[r,a] -> cards_per_artist_per_round[r,a] > 0
|
||||
awards_per_round_per_artist[r,a] -> CardsForArtist[r,a] > 0
|
||||
);
|
||||
|
||||
% Set award_bonus_per_round_per_artist = array[5] with bonus that can be added to ranking scores
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
% This file deals with dealing of new cards every Round
|
||||
|
||||
% Usable variable from here is CardsDealtPerRound[Rounds]
|
||||
array[Rounds] of var int: CardsDealtPerRound;
|
||||
|
||||
constraint CardsDealtPerRound[Round1] = 13;
|
||||
constraint CardsDealtPerRound[Round2] =
|
||||
if card(Players) < 4 then
|
||||
6
|
||||
else if card(Players) = 4 then
|
||||
4
|
||||
else
|
||||
2
|
||||
endif
|
||||
endif;
|
||||
|
||||
constraint CardsDealtPerRound[Round3] =
|
||||
if card(Players) < 4 then
|
||||
6
|
||||
else if card(Players) = 4 then
|
||||
4
|
||||
else
|
||||
2
|
||||
endif
|
||||
endif;
|
||||
|
||||
constraint CardsDealtPerRound[Round4] = if card(Players) = 2 then 3 else 0 endif;
|
|
@ -0,0 +1,34 @@
|
|||
% DOUBLE CARDS
|
||||
% - Double cards are counted as VISIBLE
|
||||
% - Double cards CANNOT breach the 6 LIMIT
|
||||
% Total number of DOUBLE CARDS for each artist = 1
|
||||
% FOR EVERY ROUND+ARTIST combination, only 1 player should have played a double card
|
||||
% TODO: Check if this is still correct after a second round
|
||||
|
||||
% Whether you played a double this round
|
||||
array[Rounds,Players,Artists] of var bool: double_played;
|
||||
|
||||
|
||||
constraint forall(a in Artists) (
|
||||
sum(p in Players, r in Rounds) (double_played[r,p,a]) = 1
|
||||
);
|
||||
|
||||
% What is the extra cards you can possibly play
|
||||
array[Rounds,Players,Artists] of var bool: bonus_due_to_double_cards;
|
||||
|
||||
constraint forall(a in Artists, r in Rounds, p in Players) (
|
||||
% If this player played more than 2 cards of this artist
|
||||
if visible_count_per_round_per_artist_per_player[r,p,a] >=2
|
||||
% And this artist is the winning artist this round
|
||||
/\ row(sorted_artists_per_round,r)[1] = a
|
||||
% And you closed this round
|
||||
/\ visible_count_per_round_per_artist_per_player[r,p,a] = max_visible_cards
|
||||
% and they are claiming their double now
|
||||
/\ double_played[r,p,a] then
|
||||
bonus_due_to_double_cards[r,p,a] = true
|
||||
else
|
||||
bonus_due_to_double_cards[r,p,a] = false
|
||||
endif
|
||||
);
|
||||
|
||||
% array[Rounds,Players] of var int: negs_due_to_double_cards;
|
|
@ -0,0 +1,14 @@
|
|||
include "globals.mzn";
|
||||
% Since the documentation is unclear, wrote this test to figure
|
||||
% out whether enums wrap around or not.
|
||||
enum Letters;
|
||||
Letters= {A,B,C};
|
||||
|
||||
var Letters: x;
|
||||
var Letters: y;
|
||||
var Letters: z;
|
||||
|
||||
constraint x = enum_next(Letters, y);
|
||||
constraint y = B;
|
||||
% This is unsatisfiable, because nothing comes after x=C
|
||||
constraint z = enum_next(Letters, x);
|
146
gameplay.mzn
146
gameplay.mzn
|
@ -5,6 +5,12 @@ include "ranking.mzn";
|
|||
include "scoring.mzn";
|
||||
include "sanity.mzn";
|
||||
include "artists.mzn";
|
||||
include "dealing.mzn";
|
||||
% Ignoring these for now
|
||||
% include "double.mzn";
|
||||
% include "drawone.mzn";
|
||||
% include "hidden.mzn";
|
||||
% include "simultaneous.mzn";
|
||||
|
||||
/*
|
||||
This file includes the core gameplay rules
|
||||
|
@ -14,65 +20,103 @@ include "artists.mzn";
|
|||
|
||||
% Calculate total cards of an artist played per round
|
||||
constraint forall (a in Artists, r in Rounds) (
|
||||
cards_per_artist_per_round[r, a] = sum(p in Players) (visible_count_per_round_per_artist_per_player[r,p,a])
|
||||
CardsForArtist[r, a] = sum(p in Players) (visible_count_per_round_per_artist_per_player[r,p,a])
|
||||
);
|
||||
|
||||
% Max number of visible cards can be 6 for any artist per player
|
||||
var 5..6: max_visible_cards;
|
||||
constraint max_visible_cards = if card(Players)>2 then 6 else 5 endif;
|
||||
var 5..6: MaxVisibleCards;
|
||||
constraint MaxVisibleCards = if card(Players)>2 then 6 else 5 endif;
|
||||
|
||||
% Maximum max_visible_cards of the artist with maximum cards
|
||||
constraint forall(r in Rounds) (max(row(cards_per_artist_per_round,r)) = max_visible_cards);
|
||||
% Maximum MaxVisibleCards of the artist with maximum cards
|
||||
constraint forall(r in Rounds) (max(row(CardsForArtist,r)) = MaxVisibleCards);
|
||||
|
||||
% second highest value should not be the max
|
||||
constraint forall(r in Rounds) (sort(row(cards_per_artist_per_round, r))[4] != max_visible_cards);
|
||||
constraint forall(r in Rounds) (sort(row(CardsForArtist, r))[4] != MaxVisibleCards);
|
||||
|
||||
% DOUBLE CARDS
|
||||
% - Double cards are counted as VISIBLE
|
||||
% - Double cards CANNOT breach the 6 LIMIT
|
||||
% Total number of DOUBLE CARDS for each artist = 1
|
||||
% FOR EVERY ROUND+ARTIST combination, only 1 player should have played a double card
|
||||
% TODO: Check if this is still correct after a second round
|
||||
constraint forall(a in Artists) (
|
||||
sum(p in Players, r in Rounds) (double_played[r,p,a]) = 1
|
||||
% Temporary variable to see how many cards you've played TOTAL per round
|
||||
array[Rounds,Players] of var int: TotalCardsPlayed;
|
||||
constraint forall(r in Rounds, p in Players) (
|
||||
% TODO: Change this to played cards from VISIBLE (hidden)
|
||||
TotalCardsPlayed[r,p] = sum(a in Artists) (visible_count_per_round_per_artist_per_player[r,p,a])
|
||||
);
|
||||
|
||||
array[Rounds,Players] of var int: max_cards_per_round_per_player;
|
||||
|
||||
% What is the extra cards you can possibly play
|
||||
array[Rounds,Players,Artists] of var bool: bonus_due_to_double_cards;
|
||||
|
||||
constraint forall(a in Artists, r in Rounds, p in Players) (
|
||||
% If this player played more than 2 cards of this artist
|
||||
if visible_count_per_round_per_artist_per_player[r,p,a] >=2
|
||||
% And this artist is the winning artist this round
|
||||
/\ row(sorted_artists_per_round,r)[1] = a
|
||||
% And you closed this round
|
||||
/\ visible_count_per_round_per_artist_per_player[r,p,a] = max_visible_cards
|
||||
% and they are claiming their double now
|
||||
/\ double_played[r,p,a] then
|
||||
bonus_due_to_double_cards[r,p,a] = true
|
||||
else
|
||||
bonus_due_to_double_cards[r,p,a] = false
|
||||
endif
|
||||
);
|
||||
|
||||
% array[Rounds,Players] of var int: negs_due_to_double_cards;
|
||||
|
||||
% constraint forall(r in Rounds, p in Players) (
|
||||
|
||||
% );
|
||||
|
||||
% Calculate maximum cards any player can play in first round
|
||||
% constraint forall(p in Players) (
|
||||
% CardsInHand[Round1,p] = 13
|
||||
% );
|
||||
|
||||
% TODO: This is actual not VISIBLE, but TOTAL cards LIMIT
|
||||
% TODO: This does not consider any of the symbols
|
||||
% IMPLIED RULE: You can max play 13 cards in Round 1
|
||||
constraint forall(p in Players) (
|
||||
sum(a in Artists) (
|
||||
visible_count_per_round_per_artist_per_player[Round1,p,a]
|
||||
) <= max_cards_per_round_per_player[Round1,p]
|
||||
array[Rounds,Players] of var int: StartingCardsInHand;
|
||||
% Round 1 Starting Hand is 13 cards
|
||||
constraint forall(p in Players) (StartingCardsInHand[Round1,p] = CardsDealtPerRound[Round1]);
|
||||
constraint forall(p in Players) (
|
||||
StartingCardsInHand[Round2,p] = StartingCardsInHand[Round1,p] - TotalCardsPlayed[Round1,p] + CardsDealtPerRound[Round2]
|
||||
);
|
||||
constraint forall(p in Players) (
|
||||
StartingCardsInHand[Round3,p] = StartingCardsInHand[Round2,p] - TotalCardsPlayed[Round2,p] + CardsDealtPerRound[Round3]
|
||||
);
|
||||
constraint forall(p in Players) (
|
||||
StartingCardsInHand[Round4,p] = StartingCardsInHand[Round3,p] - TotalCardsPlayed[Round3,p] + CardsDealtPerRound[Round4]
|
||||
);
|
||||
|
||||
% TURN ORDER STUFF
|
||||
constraint forall(r in Rounds) (
|
||||
NominalTurnCount[r] = TotalCardsPlayed[r, last_player[r]]
|
||||
);
|
||||
|
||||
%All players who played nominal turns
|
||||
var set of Players: Pn1;
|
||||
var set of Players: Pn2;
|
||||
var set of Players: Pn3;
|
||||
var set of Players: Pn4;
|
||||
%All players who played sub-nominal turns
|
||||
var set of Players: Px1;
|
||||
var set of Players: Px2;
|
||||
var set of Players: Px3;
|
||||
var set of Players: Px4;
|
||||
|
||||
set of int: emptySet = 1..0;
|
||||
|
||||
constraint Pn1 = if (first_player[Round1] < last_player[Round1]) then
|
||||
first_player[Round1]..last_player[Round1]
|
||||
else
|
||||
set_diff(Players,first_player[Round1]..last_player[Round1])
|
||||
endif;
|
||||
|
||||
|
||||
constraint Pn2 = if (first_player[Round2] < last_player[Round2]) then
|
||||
first_player[Round2]..last_player[Round2]
|
||||
else
|
||||
set_diff(Players,first_player[Round2]..last_player[Round2])
|
||||
endif;
|
||||
|
||||
|
||||
constraint Pn3 = if (first_player[Round3] < last_player[Round3]) then
|
||||
first_player[Round3]..last_player[Round3]
|
||||
else
|
||||
set_diff(Players,first_player[Round3]..last_player[Round3])
|
||||
endif;
|
||||
|
||||
|
||||
constraint Pn4 = if (first_player[Round4] < last_player[Round4]) then
|
||||
first_player[Round4]..last_player[Round4]
|
||||
else
|
||||
set_diff(Players,first_player[Round4]..last_player[Round4])
|
||||
endif;
|
||||
|
||||
constraint Px1 = set_diff(Players,Pn1);
|
||||
constraint Px2 = set_diff(Players,Pn2);
|
||||
constraint Px3 = set_diff(Players,Pn3);
|
||||
constraint Px4 = set_diff(Players,Pn4);
|
||||
|
||||
constraint forall(p in Players) (p in Pn1 -> TotalCardsPlayed[Round1, p] = NominalTurnCount[Round1]);
|
||||
constraint forall(p in Players) (p in Pn2 -> TotalCardsPlayed[Round2, p] = NominalTurnCount[Round2]);
|
||||
constraint forall(p in Players) (p in Pn3 -> TotalCardsPlayed[Round3, p] = NominalTurnCount[Round3]);
|
||||
constraint forall(p in Players) (p in Pn3 -> TotalCardsPlayed[Round4, p] = NominalTurnCount[Round4]);
|
||||
|
||||
constraint forall(p in Players) (p in Px1 -> TotalCardsPlayed[Round1, p] = NominalTurnCount[Round1] - 1);
|
||||
constraint forall(p in Players) (p in Px2 -> TotalCardsPlayed[Round2, p] = NominalTurnCount[Round2] - 1);
|
||||
constraint forall(p in Players) (p in Px3 -> TotalCardsPlayed[Round3, p] = NominalTurnCount[Round3] - 1);
|
||||
constraint forall(p in Players) (p in Px3 -> TotalCardsPlayed[Round4, p] = NominalTurnCount[Round4] - 1);
|
||||
|
||||
% Total Playable Cards for any round are set equal to the Starting Hand
|
||||
% TODO: Move this to `drawone`
|
||||
array[Rounds,Players] of var int: PlayableCards;
|
||||
constraint forall(p in Players, r in Rounds) (
|
||||
PlayableCards[r,p] = StartingCardsInHand[r,p]
|
||||
);
|
||||
|
|
|
@ -3,9 +3,9 @@ enum Players;
|
|||
enum Artists;
|
||||
enum Rounds;
|
||||
|
||||
Players = {Nemo,Jana};
|
||||
Players = {Nemo,Jana, Adam};
|
||||
Artists = {Krypto,KarlGitter,ChristinP,Yoko,LiteMetal};
|
||||
Rounds = {Round1};
|
||||
Rounds = {Round1, Round2, Round3, Round4};
|
||||
|
||||
% Number of cards per round per player per artist
|
||||
array[Rounds,Players,Artists] of var int: visible_count_per_round_per_artist_per_player;
|
||||
|
@ -19,20 +19,16 @@ array[Rounds] of var Players: last_player;
|
|||
% Total points that an artist has in a given round
|
||||
array[Rounds,Artists] of var int: total_score_per_round_per_artist;
|
||||
|
||||
% Whether you played a double this round
|
||||
array[Rounds,Players,Artists] of var bool: double_played;
|
||||
|
||||
% Score a player gets in each given round
|
||||
array[Rounds,Players] of var int: score_per_round_per_player;
|
||||
array[Rounds,Players] of var int: RoundScore;
|
||||
|
||||
% Final score of a player
|
||||
array[Players] of var int: score_per_player;
|
||||
array[Players] of var int: Score;
|
||||
|
||||
% Total number of a cards of an artist that were PLAYED this round
|
||||
array[Rounds, Artists] of var int: cards_per_artist_per_round;
|
||||
array[Rounds, Artists] of var int: CardsForArtist;
|
||||
|
||||
% Dumb constraints to help maximize score
|
||||
constraint score_per_round_per_player[Round1,Nemo] > score_per_round_per_player[Round1,Jana];
|
||||
% constraint score_per_round_per_player[Round1,Jana] > 10;
|
||||
% constraint score_per_round_per_player[Round1,Adam] > 5;
|
||||
solve maximize sum(p in Players)(score_per_player[p]);
|
||||
% Number of Turns played by the closing player this round
|
||||
array[Rounds] of var int: NominalTurnCount;
|
||||
|
||||
solve maximize Score[Nemo];
|
|
@ -5,7 +5,7 @@ array[Rounds,Artists] of var int: ranking_score_per_artist_per_round;
|
|||
array[Rounds,1..card(Artists)] of var Artists: sorted_artists_per_round;
|
||||
|
||||
% Decide the top artists by picking the cards per artist for that round, and sorting them
|
||||
constraint forall(r in Rounds)(row(sorted_artists_per_round,r)= reverse(arg_sort(row(cards_per_artist_per_round, r))));
|
||||
constraint forall(r in Rounds)(row(sorted_artists_per_round,r)= reverse(arg_sort(row(CardsForArtist, r))));
|
||||
|
||||
% Top three artists get ranking score in each round as 3,2,1 others get 0
|
||||
constraint forall(r in Rounds) (ranking_score_per_artist_per_round[r, row(sorted_artists_per_round,r)[1]] = 3);
|
||||
|
|
14
sanity.mzn
14
sanity.mzn
|
@ -1,6 +1,6 @@
|
|||
% Sanity check
|
||||
constraint forall (a in Artists, r in Rounds) (
|
||||
cards_per_artist_per_round[r,a]>=0
|
||||
CardsForArtist[r,a]>=0
|
||||
);
|
||||
% So they don't go negative
|
||||
constraint forall (a in Artists, r in Rounds, p in Players) (
|
||||
|
@ -12,10 +12,20 @@ constraint forall (a in Artists, r in Rounds) (
|
|||
ranking_score_per_artist_per_round[r,a] >=0
|
||||
);
|
||||
|
||||
% No game can have less than 1 Nominal Turn (Number of turns played by the Closing Player)
|
||||
constraint forall(r in Rounds) (NominalTurnCount[r] >=1);
|
||||
|
||||
constraint forall(r in Rounds, p in Players) (
|
||||
StartingCardsInHand[r,p] >=0
|
||||
);
|
||||
|
||||
% Round 1 Player 1
|
||||
constraint first_player[Round1] = Nemo;
|
||||
|
||||
% Visible Cards per round per player for every artist > 0
|
||||
constraint forall(a in Artists) (
|
||||
sum(p in Players, r in Rounds) (visible_count_per_round_per_artist_per_player[r,p,a])>=0
|
||||
);
|
||||
);
|
||||
|
||||
% This is a 2-5 player game
|
||||
constraint 2<= assert(card(Players)) <=5
|
|
@ -8,14 +8,12 @@ constraint forall(r in Rounds, a in Artists) (
|
|||
|
||||
% 1. Per Round
|
||||
constraint forall(r in Rounds, p in Players) (
|
||||
score_per_round_per_player[r,p] =
|
||||
|
||||
sum(a in Artists) (
|
||||
RoundScore[r,p] = sum(a in Artists) (
|
||||
visible_count_per_round_per_artist_per_player[r,p,a] * ranking_score_per_artist_per_round[r,a]
|
||||
)
|
||||
);
|
||||
|
||||
% 2. For the whole game
|
||||
constraint forall(p in Players) (
|
||||
score_per_player[p] = sum(r in Rounds) (score_per_round_per_player[r,p])
|
||||
Score[p] = sum(r in Rounds) (RoundScore[r,p])
|
||||
);
|
||||
|
|
Loading…
Reference in New Issue