diff --git a/lib/paxos.ex b/lib/paxos.ex index 1abec82..2ff0d17 100644 --- a/lib/paxos.ex +++ b/lib/paxos.ex @@ -1,6 +1,6 @@ defmodule Utils do - @min_print_level 2 + @min_print_level 3 def safecast(p, m) when p == nil, do: IO.puts('Trying to safecast #{m} with p as nil') def safecast(p, m) when is_pid(p), do: send(p, m) diff --git a/lib/server.ex b/lib/server.ex index 1f6f1cb..17b0745 100644 --- a/lib/server.ex +++ b/lib/server.ex @@ -103,7 +103,9 @@ defmodule Server do state {:get_game_state, game_id, pid_to_inform} -> - get_game_state(state, game_id, pid_to_inform) + state = get_game_state(state, game_id, pid_to_inform) + set_modifed(state, game_id) + {:make_move, game_id, move, pid_to_inform} -> try_to_play_checks(state, game_id, move, pid_to_inform) @@ -153,7 +155,13 @@ defmodule Server do defp try_to_play(state, game_id, move, pid_to_inform) do name = state.name - new_hand = get_hand_for_game_state(state.games[game_id].game_state) + + new_hand = if state.games[game_id].hand[state.name] == :- do + state.games[game_id].game_state[move] + else + get_hand_for_game_state(state.games[game_id].game_state) + end + try_propose {:make_move, game_id, name, move, new_hand} do {:decision, {:make_move, ^game_id, ^name, ^move, ^new_hand}} -> @@ -216,13 +224,15 @@ defmodule Server do defp get_hand_for_game_state(game_state) do r1 = Enum.random(0..100) - if r1 <= 20 do - :+ - else - mx = game_state |> Enum.filter(fn m -> m != :+ end) |> Enum.max() - mn = max(mx - 20, 1) - mx = max(mx - 2, 4) - Enum.random(mn..mx) + cond do + r1 <= 1 -> :b + r1 <= 5 -> :- + r1 <= 20 -> :+ + true -> + mx = game_state |> Enum.filter(fn m -> m != :+ end) |> Enum.max() + mn = max(mx - 20, 1) + mx = max(mx - 2, 4) + Enum.random(mn..mx) end end @@ -264,7 +274,7 @@ defmodule Server do end defp set_modifed(state, game, val \\ false) do - or_state not is_finished(state, game) and state.games[game] != :not_playing_in_game do + or_state not is_finished(state, game) and state.games[game] != :not_playing_in_game and state.games[game] != nil do %{state | games: Map.put(state.games, game, %{state.games[game] | modified: val})} end end @@ -298,6 +308,7 @@ defmodule Server do if b == a do case b do :+ -> simplify_game_state_pluses(tl, indexed_game_state) + :b -> simplify_game_state_pluses(tl, indexed_game_state) n -> list = indexed_game_state |> @@ -319,6 +330,33 @@ defmodule Server do end end + defp simplify_game_state_pluses([{:b, i} | tl], indexed_game_state) do + before_i = get_index(indexed_game_state, i, -1) + after_i = get_index(indexed_game_state, i, 1) + + if before_i != after_i do + {b, b_i} = Enum.at(indexed_game_state, before_i) + {a, a_i} = Enum.at(indexed_game_state, after_i) + + a = if is_atom(a) do 1 else a end + b = if is_atom(b) do 1 else b end + + list = + indexed_game_state |> + Enum.map(fn {x, ti} -> if ti == i, do: {{:merged, trunc(:math.floor((a + b) / 2))}, i}, else: {x, ti} end) |> + Enum.filter(fn {x, ti} -> cond do + b_i == ti -> false + a_i == ti -> false + true -> true + end + end) |> + reindex() + {true, expand_merge(list)} + else + simplify_game_state_pluses(tl, indexed_game_state) + end + end + defp is_merged(item) do case item do {:merged, _} -> true @@ -389,6 +427,7 @@ defmodule Server do indexed_game_state |> Enum.filter(fn x -> case x do {:+, _} -> true + {:b, _} -> true _ -> false end end) |> @@ -413,8 +452,12 @@ defmodule Server do %{state | instance: state.instance + 1 } game -> game_state = game.game_state - {b, e} = Enum.split(game_state, pos_move) - game_state = b ++ [ game.hand[player_name] ] ++ e + game_state = if game.hand[player_name] == :- do + List.delete_at(game_state, pos_move) + else + {b, e} = Enum.split(game_state, pos_move) + b ++ [ game.hand[player_name] ] ++ e + end game_state = simplify_game_state(game_state) hand = Map.put(game.hand, player_name, new_hand) game = %{game| hand: hand, game_state: game_state, modified: true } @@ -561,7 +604,7 @@ defmodule Client do to_name() |> interpolate() |> fill() |> - printpt(pad(to_name(hand))) + printpt(to_name(hand)) false end @@ -580,9 +623,10 @@ defmodule Client do case res do :timeout -> log("Could to not comunicate with the server") - {:not_exists} -> play_game(process, game_id) - {:not_playing} -> play_game(process, game_id) - {:game_finished, _} -> play_game(process, game_id) + {:not_exists} -> log("Game does not exist") + {:not_playing} -> log("Not Playing in that game") + {:game_finished, score} -> log("Game finsihed, #{score}") + {:game_does_not_exist} -> log("Got game does not exist") {:player_moved_before, _, _} -> log("Player Moved before you did please check the map and try again") play_game(process, game_id) @@ -613,12 +657,12 @@ defmodule Client do res = Server.make_move(process, game_id, n) case res do :timeout -> log("Could to not comunicate with the server") - {:not_exists} -> play_game(process, game_id) - {:not_playing} -> play_game(process, game_id) - {:game_finished, _} -> play_game(process, game_id) + {:not_exists} -> control_game(process, game_id) + {:not_playing} -> control_game(process, game_id) + {:game_finished, _} -> control_game(process, game_id) {:player_moved_before, _, _} -> log("Player Moved before you did please check the map and try again") - play_game(process, game_id) + control_game(process, game_id) {:invalid_move} -> raise "Invalid Move" {:state, _, _} -> control_game(process, game_id) end @@ -631,7 +675,7 @@ defmodule Client do end - def display_game(process, game_id) do + def display_game(process, game_id, temp_game \\ [], temp_hand \\ []) do game = Server.get_game_state(process, game_id) cont = case game do @@ -641,36 +685,37 @@ defmodule Client do {:game_finished, score} -> log("Game finsihed, #{score}") {:game_does_not_exist} -> log("Got game does not exist") {:state, game_state, hand} -> - IO.ANSI.clear() - game_state |> - to_name() |> - interpolate() |> - fill() |> - printpt(pad(to_name(hand))) - Process.sleep(1000) - display_game(process, game_id) + if temp_game != game_state or temp_hand != hand do + # IO.ANSI.clear() + game_state |> + to_name() |> + interpolate() |> + fill() |> + printpt(to_name(hand)) + Process.sleep(1000) + display_game(process, game_id, game_state, hand) + else + display_game(process, game_id, temp_game, temp_hand) + end end end def to_name(list) when is_list(list), do: list |> Enum.map(fn x -> to_name(x) end) - def to_name(atom) when atom == :+, do: IO.ANSI.color_background(9) <> IO.ANSI.color(15) <> "#{:atom}" <> IO.ANSI.reset() + def to_name(atom) when atom == :+, do: IO.ANSI.color_background(9) <> IO.ANSI.color(15) <> " + " <> IO.ANSI.reset() + def to_name(atom) when atom == :-, do: IO.ANSI.color_background(21) <> IO.ANSI.color(15) <> " - " <> IO.ANSI.reset() + def to_name(atom) when atom == :b, do: IO.ANSI.color_background(232) <> IO.ANSI.color(15) <> " b " <> IO.ANSI.reset() def to_name(atom) when is_atom(atom), do: atom def to_name(i) do letter = [ "H", "He", "Li", "Be", "B", "C", "N", "O", "F", "Ne", "Na", "Mg", "Al", "Si", "P", "S", "Cl", "Ar", "K", "Ca", "Sc", "Ti", "V", "Cr", "Mn", "Fe", "Co", "Ni", "Cu", "Zn", "Ga", "Ge", "As", "Se", "Br", "Kr", "Rb", "Sr", "Y", "Zr", "Nb", "Mo", "Tc", "Ru", "Rh", "Pd", "Ag", "Cd", "In", "Sn", "Sb", "Te", "I", "Xe", "Cs", "Ba", "La", "Ce", "Pr", "Nd", "Pm", "Sm", "Eu", "Gd", "Tb", "Dy", "Ho", "Er", "Tm", "Yb", "Lu", "Hf", "Ta", "W", "Re", "Os", "Ir", "Pt", "Au", "Hg", "Tl", "Pb", "Bi", "Po", "At", "Rn", "Fr", "Ra", "Ac", "Th", "Pa", "U", "Np", "Pu", "Am", "Cm", "Bk", "Cf", "Es", "Fm", "Md", "No", "Lr", "Rf", "Db", "Sg", "Bh", "Hs", "Mt", "Ds", "Rg", "Cn", "Nh", "Fl", "Mc", "Lv", "Ts", "Og" ] |> Enum.at(i - 1) color = [46,45,138,19,11,140,8,47,57,159,72,48,55,35,251,188,107,110,21,11,156,134,128,179,140,234,14,90,206,7,249,209,253,123,192,165,234,136,198,208,43,34,215,127,23,250,177,237,124,202,229, 63,206,220,224,109,202,113,253,7,243,26,160,65,39,112,57,75, 252,82,213,186,68,243,134,100,226,48,90,134,208,102,25,106,72, 242,26,59,166,26,187,54,194,165,97,219,186,130,7,154,233,85, 130,67,43,200,90,60,148,49,161,110,247,116,223,159,132,132] |> Enum.at(i - 1) |> IO.ANSI.color() - color <> letter <> IO.ANSI.reset() + color <> String.pad_leading("#{letter}", 3, " ") <> IO.ANSI.reset() end def interpolate(list) do [list, 0..length(list) - 1] |> Enum.zip() |> - Enum.reduce([], fn {v, i}, acc -> acc ++ [i, v] end) |> - Enum.map(fn x -> pad(x) end) - end - - def pad(elem) do - String.pad_leading("#{elem}", 3, " ") + Enum.reduce([], fn {v, i}, acc -> acc ++ [String.pad_leading("#{i}", 3, " "), v] end) end def grow_empty_list(t, i, acc) when i == 0, do: t ++ acc diff --git a/notes b/notes new file mode 100644 index 0000000..d36217c --- /dev/null +++ b/notes @@ -0,0 +1,191 @@ +procs = Enum.to_list(1..3) |> Enum.map(fn m -> :"p#{m}") +pids = Enum.map(procs, fn p -> ShopServer.start(p, procs)) +pids |> Enum.map(fn p -> Process.exit(p, :kill) end) + + + +max = 100 + +1..max |> Enum.to_list() |> Enum.reduce(%{}, fn n, acc -> Map.put(acc, n, :not_reseverd) end) |> + + + + + + + + + " # " + " #1# " + " # " + " # # " + " #0# #2# " + " # # " + " # " + " #4# " + " # " + + + " # " + " #1# " + " # " + " # # " + " #0# #2# " + " # # " + " # # " + " #7# #3# " + " # # " + " # # " + " #6# #4# " + " # # " + " # " + " #5# " + " # " + + + + + + " # " + " #1# " + " # " + " # # " + " #0# #2# " + " # # " + " #11 #3# " + " # # " + " # # " + " #10 #4# " + " # # " + " # # " + " #9# #5# " + " # # " + " #8# #6# " + " # # " + " # " + " #7# " + " # " + + + + + + " # " + " #1# " + " # " + " # # " + " #0# #2# " + " #15 #3# " + " # # " + " # # " + " #14 #4# " + " # # " + " # # " + " #13 #5# " + " # # " + " # # " + " #12 #6# " + " # # " + " # # " + " #11 #7# " + " #10 #8# " + " # # " + " # " + " #9# " + " # " + + + + + + + + + + " # " + " #1# " + " # " + " # # " + " #0# #2# " + " #19 #3# " + " # # " + " # # " + " #18 #4# " + " #17 #5# " + " # # " + " # # " + " #16 #6# " + " # # " + " #15 #7# " + " # # " + " #14 #8# " + " # # " + " # # " + " #13 #9# " + " #12 #10 " + " # # " + " # " + " #11 " + " # " + + + + + + " # " + " #1# " + " # " + " # # " + " #0# #2# " + " #23 #3# " + " # # " + " #22 #4# " + " #21 #5# " + " # # " + " #20 #6# " + " # # " + " # # " + " #19 #7# " + " # # " + " # # " + " #18 #8# " + " # # " + " #17 #9# " + " #16 #10 " + " # # " + " #15 #11 " + " #14 #12 " + " # # " + " # " + " #13 " + " # " + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +