The problem is here: https://exercism.org/tracks/euphoria/exercises/camicia/edit
a sample error would be:
failed: three cards, one trick, expected: {
Here’s my code:
include std/sequence.e
integer turn = 0, num_tricks = 0, cards_played = 0, cards_left_to_pay = 0, payee = 0
sequence pile = {}, loop_status = "finished", playerA, playerB, prev_hands = {}
procedure play_card(integer p)
if p = 0 then
pile = prepend(pile, playerA[1])
playerA = tail(playerA)
else
pile = prepend(pile, playerB[1])
playerB = tail(playerB)
end if
cards_played += 1
end procedure
function get_pay_card()
return match(pile[1], "JQKA")
end function
function replace_nums(sequence hand)
for i = 1 to length(hand) do
if match(hand[i], "JQKA") <= 0 then
hand[i] = "X"
end if
end for
-- printf(1, "Hand: %s\n", { join(hand) })
return hand
end function
function add_hands(sequence hands)
sequence masked_hands = { replace_nums(hands[1]), replace_nums(hands[2]) }
if set_contains_seqs(prev_hands, masked_hands) then
-- printf(1, "Same hand, needle %s, haystack %s\n\n", { join(playerA), join(apply(player_a_prev_hands, routine_id("join")), ", ") })
return 0
else
prev_hands &= { masked_hands }
return 1
end if
end function
function set_contains_seqs(sequence haystack, sequence masked_hands)
-- printf(1, "\nset_contains_seq, needle %s, haystack %s\n\n", { join(needle), join(apply(haystack, routine_id("join")), ", ") })
for i = 1 to length(haystack) do
-- if equal_ignoring_numbers(haystack[i][1], masked_hands[1]) and equal_ignoring_numbers(haystack[i][2], masked_hands[2]) then
if equal(haystack[i][1], masked_hands[1]) and equal(haystack[i][2], masked_hands[2]) then
-- printf(1, "\nset_contains_seq indeed, needle %s, haystack %s\n\n", { join(needle), join(apply(haystack, routine_id("join")), ", ") })
return 1
end if
end for
return 0
end function
/*
function equal_ignoring_numbers(sequence s1, sequence s2)
if length(s1) != length(s2) then
-- printf(1, "equal_ignoring_numbers diff length, s1 %s, s2 %s\n", { join(s1), join(s2) })
return 0
else
for i = 1 to length(s1) do
integer i1 = match(s1[i], "JQKA")
integer i2 = match(s2[i], "JQKA")
if i1 > 0 and i1 != i2 then
-- printf(1, "equal_ignoring_numbers unequal at %d, s1 %s, s2 %s\n", { i, join(s1), join(s2) })
return 0
elsif i2 > 0 and i2 != i1 then
-- printf(1, "equal_ignoring_numbers unequal at %d, s1 %s, s2 %s\n", { i, join(s1), join(s2) })
return 0
end if
end for
-- printf(1, "equal_ignoring_numbers equal, s1 %s, s2 %s\n", { join(s1), join(s2) })
return 1
end if
end function
*/
procedure take_pile(integer p)
if p = 0 then
playerA = playerA & reverse(pile)
else
playerB = playerB & reverse(pile)
end if
pile = {}
num_tricks += 1
-- printf(1, "new num_tricks %d, cards_played %d.\n", { num_tricks, cards_played })
end procedure
public function simulateGame(sequence _playerA, sequence _playerB)
playerA = _playerA
playerB = _playerB
while 1 do
-- printf(1, "\nplayer %d to play, pile %s, playerA %s, playerB %s\n", { turn, join(pile), join(playerA), join(playerB) })
if turn = 0 and length(playerA) < 1 then
-- printf(1, "player 1 out, p 2 takes the pile")
take_pile(1)
exit
elsif turn = 1 and length(playerB) < 1 then
-- printf(1, "player 2 out, p 1 takes the pile")
take_pile(0)
exit
else
if not(add_hands({ playerA, playerB })) then
loop_status = "loop"
goto "player_out"
end if
play_card(turn)
end if
-- printf(1, "player %d played, pile %s, playerA %s, playerB %s\n", { turn, join(pile), join(playerA), join(playerB) })
cards_left_to_pay = get_pay_card()
if cards_left_to_pay < 1 then
turn = 1 - turn
else
payee = 1 - turn
while cards_left_to_pay > 0 do
if payee = 0 then
if length(playerA) < 1 then
take_pile(1)
-- printf(1, "player 0 out\n")
goto "player_out"
end if
else
if length(playerB) < 1 then
take_pile(0)
-- printf(1, "player 1 out\n")
goto "player_out"
end if
end if
play_card(payee)
-- printf(1, "player %d fined, pile %s, playerA %s, playerB %s\n", { payee, join(pile), join(playerA), join(playerB) })
integer current_top_card = get_pay_card()
if current_top_card > 0 then
payee = 1 - payee
cards_left_to_pay = current_top_card
-- printf(1, "new payment card, cards left %d, new payee %d\n", { cards_left_to_pay, payee })
else
cards_left_to_pay -= 1
end if
end while
-- payee is done paying, turn is other player, other player gets the pile
turn = 1 - payee
-- printf(1, "end of round, taking pile.\n")
take_pile(turn)
if length(playerB) < 1 or length(playerA) < 1 then
-- printf(1, "other player out\n")
goto "player_out"
end if
end if
end while
label "player_out"
printf(1, "Done. turn %d, pile %s, playerA %s, playerA replaced %s, playerB %s, loop_status %s, cards_played %d, num_tricks %d\n",
{ turn, join(pile), join(playerA), join(replace_nums(playerA)), join(playerB), loop_status, cards_played, num_tricks })
return { {"status", loop_status}, {"cards", cards_played}, {"tricks", num_tricks} }
end function