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 either
This commit is contained in:
Nemo 2020-06-11 03:45:17 +05:30
parent 3650ce1757
commit da83f6eda1
9 changed files with 195 additions and 72 deletions

View File

@ -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 % awards can only be given if an artist's card was played that turn
constraint forall(r in Rounds, a in Artists) ( 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 % Set award_bonus_per_round_per_artist = array[5] with bonus that can be added to ranking scores

27
dealing.mzn Normal file
View File

@ -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;

34
double.mzn Normal file
View File

@ -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;

14
enumtest.mzn Normal file
View File

@ -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);

View File

@ -5,6 +5,12 @@ include "ranking.mzn";
include "scoring.mzn"; include "scoring.mzn";
include "sanity.mzn"; include "sanity.mzn";
include "artists.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 This file includes the core gameplay rules
@ -14,65 +20,103 @@ include "artists.mzn";
% Calculate total cards of an artist played per round % Calculate total cards of an artist played per round
constraint forall (a in Artists, r in Rounds) ( 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 % Max number of visible cards can be 6 for any artist per player
var 5..6: max_visible_cards; var 5..6: MaxVisibleCards;
constraint max_visible_cards = if card(Players)>2 then 6 else 5 endif; constraint MaxVisibleCards = if card(Players)>2 then 6 else 5 endif;
% Maximum max_visible_cards of the artist with maximum cards % Maximum MaxVisibleCards of the artist with maximum cards
constraint forall(r in Rounds) (max(row(cards_per_artist_per_round,r)) = max_visible_cards); constraint forall(r in Rounds) (max(row(CardsForArtist,r)) = MaxVisibleCards);
% second highest value should not be the max % 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 % Temporary variable to see how many cards you've played TOTAL per round
% - Double cards are counted as VISIBLE array[Rounds,Players] of var int: TotalCardsPlayed;
% - Double cards CANNOT breach the 6 LIMIT constraint forall(r in Rounds, p in Players) (
% Total number of DOUBLE CARDS for each artist = 1 % TODO: Change this to played cards from VISIBLE (hidden)
% FOR EVERY ROUND+ARTIST combination, only 1 player should have played a double card TotalCardsPlayed[r,p] = sum(a in Artists) (visible_count_per_round_per_artist_per_player[r,p,a])
% 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
); );
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 % Calculate maximum cards any player can play in first round
% constraint forall(p in Players) ( array[Rounds,Players] of var int: StartingCardsInHand;
% CardsInHand[Round1,p] = 13 % Round 1 Starting Hand is 13 cards
% ); constraint forall(p in Players) (StartingCardsInHand[Round1,p] = CardsDealtPerRound[Round1]);
constraint forall(p in Players) (
% TODO: This is actual not VISIBLE, but TOTAL cards LIMIT StartingCardsInHand[Round2,p] = StartingCardsInHand[Round1,p] - TotalCardsPlayed[Round1,p] + CardsDealtPerRound[Round2]
% 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) (
constraint forall(p in Players) ( StartingCardsInHand[Round3,p] = StartingCardsInHand[Round2,p] - TotalCardsPlayed[Round2,p] + CardsDealtPerRound[Round3]
sum(a in Artists) ( );
visible_count_per_round_per_artist_per_player[Round1,p,a] constraint forall(p in Players) (
) <= max_cards_per_round_per_player[Round1,p] 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]
); );

View File

@ -3,9 +3,9 @@ enum Players;
enum Artists; enum Artists;
enum Rounds; enum Rounds;
Players = {Nemo,Jana}; Players = {Nemo,Jana, Adam};
Artists = {Krypto,KarlGitter,ChristinP,Yoko,LiteMetal}; Artists = {Krypto,KarlGitter,ChristinP,Yoko,LiteMetal};
Rounds = {Round1}; Rounds = {Round1, Round2, Round3, Round4};
% Number of cards per round per player per artist % Number of cards per round per player per artist
array[Rounds,Players,Artists] of var int: visible_count_per_round_per_artist_per_player; 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 % Total points that an artist has in a given round
array[Rounds,Artists] of var int: total_score_per_round_per_artist; 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 % 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 % 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 % 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 % Number of Turns played by the closing player this round
constraint score_per_round_per_player[Round1,Nemo] > score_per_round_per_player[Round1,Jana]; array[Rounds] of var int: NominalTurnCount;
% constraint score_per_round_per_player[Round1,Jana] > 10;
% constraint score_per_round_per_player[Round1,Adam] > 5; solve maximize Score[Nemo];
solve maximize sum(p in Players)(score_per_player[p]);

View File

@ -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; 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 % 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 % 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); constraint forall(r in Rounds) (ranking_score_per_artist_per_round[r, row(sorted_artists_per_round,r)[1]] = 3);

View File

@ -1,6 +1,6 @@
% Sanity check % Sanity check
constraint forall (a in Artists, r in Rounds) ( 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 % So they don't go negative
constraint forall (a in Artists, r in Rounds, p in Players) ( 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 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 % Round 1 Player 1
constraint first_player[Round1] = Nemo; constraint first_player[Round1] = Nemo;
% Visible Cards per round per player for every artist > 0 % Visible Cards per round per player for every artist > 0
constraint forall(a in Artists) ( constraint forall(a in Artists) (
sum(p in Players, r in Rounds) (visible_count_per_round_per_artist_per_player[r,p,a])>=0 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

View File

@ -8,14 +8,12 @@ constraint forall(r in Rounds, a in Artists) (
% 1. Per Round % 1. Per Round
constraint forall(r in Rounds, p in Players) ( constraint forall(r in Rounds, p in Players) (
score_per_round_per_player[r,p] = RoundScore[r,p] = sum(a in Artists) (
sum(a in Artists) (
visible_count_per_round_per_artist_per_player[r,p,a] * ranking_score_per_artist_per_round[r,a] visible_count_per_round_per_artist_per_player[r,p,a] * ranking_score_per_artist_per_round[r,a]
) )
); );
% 2. For the whole game % 2. For the whole game
constraint forall(p in Players) ( 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])
); );