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

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 "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
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) (
sum(a in Artists) (
visible_count_per_round_per_artist_per_player[Round1,p,a]
) <= max_cards_per_round_per_player[Round1,p]
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]
);

View File

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

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

View File

@ -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,6 +12,13 @@ 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;
@ -19,3 +26,6 @@ constraint first_player[Round1] = Nemo;
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

View File

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