diff --git a/artists.mzn b/artists.mzn new file mode 100644 index 0000000..7025162 --- /dev/null +++ b/artists.mzn @@ -0,0 +1,7 @@ +% Constraints per artist +% TODO: This is also TOTAL card limit, not visible +constraint sum(p in Players, r in Rounds) (visible_count_per_round_per_artist_per_player[r,p,LiteMetal]) <=17; +constraint sum(p in Players, r in Rounds) (visible_count_per_round_per_artist_per_player[r,p,Yoko]) <=18; +constraint sum(p in Players, r in Rounds) (visible_count_per_round_per_artist_per_player[r,p,ChristinP]) <=19; +constraint sum(p in Players, r in Rounds) (visible_count_per_round_per_artist_per_player[r,p,KarlGitter]) <=20; +constraint sum(p in Players, r in Rounds) (visible_count_per_round_per_artist_per_player[r,p,Krypto]) <=21; diff --git a/awards.mzn b/awards.mzn new file mode 100644 index 0000000..1548b72 --- /dev/null +++ b/awards.mzn @@ -0,0 +1,31 @@ +/** + AWARDS + This file deals with the awards, which gives 2 points + cumulative score benefit to the artist starting from the round + the award was played in + + There are 5 awards - one per artist + */ + +% Whether an artist won an award in a given round +array[Rounds,Artists] of var bool: awards_per_round_per_artist; + +array[Rounds,Artists] of var int: award_bonus_per_round_per_artist; + +% Total number of awards for each artist = 1 +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 +); + +% Set award_bonus_per_round_per_artist = array[5] with bonus that can be added to ranking scores +constraint forall(r in Rounds, a in Artists) ( + award_bonus_per_round_per_artist[r,a] = + if awards_per_round_per_artist[r,a] then + 2 + else + 0 + endif +); \ No newline at end of file diff --git a/functions.mzn b/functions.mzn index e69de29..e97d409 100644 --- a/functions.mzn +++ b/functions.mzn @@ -0,0 +1,5 @@ +function set of Players: PlayersWhoMissedTurn(int: p_first, int: p_last) = + if p_last > p_first then + diff(Players, ) + else + endif \ No newline at end of file diff --git a/gameplay.mzn b/gameplay.mzn new file mode 100644 index 0000000..82d9c07 --- /dev/null +++ b/gameplay.mzn @@ -0,0 +1,78 @@ +include "alldifferent.mzn"; +include "globals.mzn"; +include "awards.mzn"; +include "ranking.mzn"; +include "scoring.mzn"; +include "sanity.mzn"; +include "artists.mzn"; + +/* + This file includes the core gameplay rules + ie, how many cards are getting played each round + who plays the closing card etc. + */ + +% 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]) +); + +% 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; + +% 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); + +% 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); + +% 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 +); + +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] +); diff --git a/modernart-game.mzn b/modernart-game.mzn deleted file mode 100644 index 6af6618..0000000 --- a/modernart-game.mzn +++ /dev/null @@ -1,117 +0,0 @@ -include "alldifferent.mzn"; -include "globals.mzn"; -include "modernart-sanity.mzn"; - -% Constraints per artist -% TODO: This is also TOTAL card limit, not visible -constraint sum(p in Players, r in Rounds) (visible_count_per_round_per_artist_per_player[r,p,LiteMetal]) <=17; -constraint sum(p in Players, r in Rounds) (visible_count_per_round_per_artist_per_player[r,p,Yoko]) <=18; -constraint sum(p in Players, r in Rounds) (visible_count_per_round_per_artist_per_player[r,p,ChristinP]) <=19; -constraint sum(p in Players, r in Rounds) (visible_count_per_round_per_artist_per_player[r,p,KarlGitter]) <=20; -constraint sum(p in Players, r in Rounds) (visible_count_per_round_per_artist_per_player[r,p,Krypto]) <=21; - -constraint sum(p in Players, r in Rounds) (visible_count_per_round_per_artist_per_player[r,p,LiteMetal])>=0; -constraint sum(p in Players, r in Rounds) (visible_count_per_round_per_artist_per_player[r,p,Yoko]) >=0; -constraint sum(p in Players, r in Rounds) (visible_count_per_round_per_artist_per_player[r,p,ChristinP])>=0; -constraint sum(p in Players, r in Rounds) (visible_count_per_round_per_artist_per_player[r,p,KarlGitter])>=0; -constraint sum(p in Players, r in Rounds) (visible_count_per_round_per_artist_per_player[r,p,Krypto])>=0; - -% 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]) -); - - -% Calculate total score per player -constraint forall(r in Rounds, p in Players) ( - score_per_round_per_player[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]) -); -constraint forall(p in Players) ( - score_per_player[p] = sum(r in Rounds) (score_per_round_per_player[r,p]) -); - -% 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; -% 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); -% 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); - -% Decide the top artists by picikng 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)))); - -% 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)[2]] = 2); -constraint forall(r in Rounds) (ranking_score_per_artist_per_round[r, row(sorted_artists_per_round,r)[3]] = 1); -constraint forall(r in Rounds) (ranking_score_per_artist_per_round[r, row(sorted_artists_per_round,r)[4]] = 0); -constraint forall(r in Rounds) (ranking_score_per_artist_per_round[r, row(sorted_artists_per_round,r)[5]] = 0); - -% AWARDS -% Total number of awards for each artist = 1 -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] = 1 -> cards_per_artist_per_round[r,a] > 0 -); - -% 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 -); - -% Score = ranking_score + award_score if an award was given this round -constraint forall(r in Rounds, a in Artists) ( - total_score_per_round_per_artist[r,a] = - if awards_per_round_per_artist[r,a] then - ranking_score_per_artist_per_round[r,a] + 2 - else - ranking_score_per_artist_per_round[r,a] - endif -); - -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) ( - max_cards_per_round_per_player[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] -); diff --git a/modernart.mzn b/modernart.mzn index ab0979e..5587b7c 100644 --- a/modernart.mzn +++ b/modernart.mzn @@ -1,9 +1,9 @@ -include "modernart-game.mzn"; +include "gameplay.mzn"; enum Players; enum Artists; enum Rounds; -Players = { Nemo, Jana}; +Players = {Nemo,Jana}; Artists = {Krypto,KarlGitter,ChristinP,Yoko,LiteMetal}; Rounds = {Round1}; @@ -16,21 +16,12 @@ array[Rounds] of var Players: first_player; % Closing player every Round array[Rounds] of var Players: last_player; -% How much score was made by each artist in each round by just RANKING -array[Rounds,Artists] of var int: ranking_score_per_artist_per_round; - % Total points that an artist has in a given round array[Rounds,Artists] of var int: total_score_per_round_per_artist; -% Whether an artist won an award in a given round -array[Rounds,Artists] of var bool: awards_per_round_per_artist; - % Whether you played a double this round array[Rounds,Players,Artists] of var bool: double_played; -% Winning artists for each round (just-by-ranking) -array[Rounds,1..card(Artists)] of var Artists: sorted_artists_per_round; - % Score a player gets in each given round array[Rounds,Players] of var int: score_per_round_per_player; diff --git a/ranking.mzn b/ranking.mzn new file mode 100644 index 0000000..75cf873 --- /dev/null +++ b/ranking.mzn @@ -0,0 +1,15 @@ +% How much score was made by each artist in each round by just RANKING +array[Rounds,Artists] of var int: ranking_score_per_artist_per_round; + +% Winning artists for each round (just-by-ranking) +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)))); + +% 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)[2]] = 2); +constraint forall(r in Rounds) (ranking_score_per_artist_per_round[r, row(sorted_artists_per_round,r)[3]] = 1); +constraint forall(r in Rounds) (ranking_score_per_artist_per_round[r, row(sorted_artists_per_round,r)[4]] = 0); +constraint forall(r in Rounds) (ranking_score_per_artist_per_round[r, row(sorted_artists_per_round,r)[5]] = 0); \ No newline at end of file diff --git a/modernart-sanity.mzn b/sanity.mzn similarity index 63% rename from modernart-sanity.mzn rename to sanity.mzn index 5824b5f..00524f6 100644 --- a/modernart-sanity.mzn +++ b/sanity.mzn @@ -13,4 +13,9 @@ constraint forall (a in Artists, r in Rounds) ( ); % Round 1 Player 1 -constraint first_player[Round1] = Nemo; \ No newline at end of file +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 +); \ No newline at end of file diff --git a/scoring.mzn b/scoring.mzn new file mode 100644 index 0000000..74d25d5 --- /dev/null +++ b/scoring.mzn @@ -0,0 +1,21 @@ +% Score = ranking_score + award_score if an award was given this round +constraint forall(r in Rounds, a in Artists) ( + total_score_per_round_per_artist[r,a] = + ranking_score_per_artist_per_round[r,a] + award_bonus_per_round_per_artist[r,a] +); + +% Calculate total score per player + +% 1. Per Round +constraint forall(r in Rounds, p in Players) ( + score_per_round_per_player[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]) +);