diff --git a/app/src/main/java/fr/ynerant/tarot/Game.java b/app/src/main/java/fr/ynerant/tarot/Game.java index a38bf28..e12fdf7 100644 --- a/app/src/main/java/fr/ynerant/tarot/Game.java +++ b/app/src/main/java/fr/ynerant/tarot/Game.java @@ -4,24 +4,30 @@ import android.preference.PreferenceManager; import android.util.SparseArray; import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.TypeAdapter; import com.google.gson.reflect.TypeToken; +import com.google.gson.stream.JsonReader; +import com.google.gson.stream.JsonToken; +import com.google.gson.stream.JsonWriter; import java.io.IOException; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Set; import java.util.concurrent.Executors; public class Game { + private static final Gson GSON; private static final SparseArray GAMES = new SparseArray<>(); public int id; - public GameType type; - public Set players; + public GameType gameType; + public List players; public Bet bet; public Player attacker; public Player follower; @@ -29,19 +35,60 @@ public class Game { // public boolean little, twenty_one, excuse; public int ends; public int handle; - public Map miseries; + public List miseries; public boolean littleForAttacker, littleForDefenser; public boolean chelemAnnounced, chelemRealized; + public List points; + + static { + GSON = new GsonBuilder().registerTypeAdapter(Player.class, new TypeAdapter() { + @Override + public void write(JsonWriter out, Player value) throws IOException { + if (value == null) + out.nullValue(); + else + out.value(value.getId()); + } + + @Override + public Player read(JsonReader in) throws IOException { + if (in.peek() == JsonToken.NULL) { + in.nextNull(); + return null; + } + + return Player.getPlayerById(in.nextInt()); + } + }).registerTypeAdapter(Game.GameType.class, new TypeAdapter() { + @Override + public void write(JsonWriter out, GameType value) throws IOException { + if (value == null) + out.nullValue(); + else + out.value(value.getNbPlayers()); + } + + @Override + public GameType read(JsonReader in) throws IOException { + if (in.peek() == JsonToken.NULL) { + in.nextNull(); + return null; + } + + return Game.GameType.values()[3 + in.nextInt()]; + } + }).create(); + } public int getId() { return id; } - public GameType getType() { - return type; + public GameType getGameType() { + return gameType; } - public Set getPlayers() { + public List getPlayers() { return players; } @@ -69,7 +116,7 @@ public class Game { return handle; } - public Map getMiseries() { + public List getMiseries() { return miseries; } @@ -89,7 +136,7 @@ public class Game { return chelemRealized; } - public int calculateScore() { + public void calculateScores() { // int ends = (little ? 1 : 0) + (twenty_one ? 1 : 0) + (excuse ? 1 : 0); int bound = ends == 0 ? 56 : ends == 1 ? 51 : ends == 2 ? 41 : 36; boolean win = attackScore >= bound; @@ -119,11 +166,68 @@ public class Game { else if (chelemRealized) score += 200; - return score; + attackScore = score; + + Map scores = new HashMap<>(); + + for (int i = 0; i < getGameType().getNbPlayers(); ++i) { + Player p = players.get(i); + + int playerScore = 0; + if (p != attacker && p != follower) + playerScore = -score; + else { + if (p == attacker) + playerScore += getGameType().getAttackMultiplier() * score; + if (p == follower) + playerScore += getGameType().getFollowMultiplier() * score; + } + + scores.put(p, playerScore); + } + + for (int i = 0; i < getGameType().getNbPlayers(); ++i) { + System.err.println(getMiseries()); + if (getMiseries().get(i)) { + //noinspection ConstantConditions + scores.put(players.get(i), scores.get(players.get(i)) + 10 * (getGameType().getNbPlayers() - 1)); + for (int j = 0; j < getGameType().getNbPlayers(); ++j) { + if (i == j) + continue; + //noinspection ConstantConditions + scores.put(players.get(j), scores.get(players.get(j)) - 10); + } + } + } + + points = new ArrayList<>(); + for (int i = 0; i < getGameType().getNbPlayers(); ++i) { + points.add(scores.get(players.get(i))); + } + } + + public String toJson() { + return GSON.toJson(this); } public enum GameType { - THREE_PLAYERS, FOUR_PLAYERS, FIVE_PLAYERS, SIX_PLAYERS; + THREE_PLAYERS(2, 0), FOUR_PLAYERS(3, 0), FIVE_PLAYERS(2, 1), SIX_PLAYERS(3, 1); + + private final int attackMultiplier; + private final int followMultiplier; + + GameType(int attack, int follow) { + this.attackMultiplier = attack; + this.followMultiplier = follow; + } + + public int getAttackMultiplier() { + return attackMultiplier; + } + + public int getFollowMultiplier() { + return followMultiplier; + } public int getNbPlayers() { return ordinal() + 3; @@ -170,7 +274,7 @@ public class Game { co.setRequestProperty("token", PreferenceManager.getDefaultSharedPreferences(MainActivity.INSTANCE).getString("token", null)); co.connect(); - final List games = new Gson().fromJson(new InputStreamReader(co.getInputStream()), new TypeToken>(){}.getType()); + final List games = GSON.fromJson(new InputStreamReader(co.getInputStream()), new TypeToken>(){}.getType()); GAMES.clear(); for (Game g : games) { GAMES.put(g.getId(), g); diff --git a/app/src/main/java/fr/ynerant/tarot/Player.java b/app/src/main/java/fr/ynerant/tarot/Player.java index b9d1cb5..ba04f67 100644 --- a/app/src/main/java/fr/ynerant/tarot/Player.java +++ b/app/src/main/java/fr/ynerant/tarot/Player.java @@ -31,7 +31,7 @@ public class Player { private int score3, score4, score5, score6; - private int getId() { + public int getId() { return id; } @@ -97,6 +97,10 @@ public class Player { return PLAYERS.values(); } + public static Player getPlayerById(int id) { + return PLAYERS.get(id); + } + @NonNull @Override public String toString() { diff --git a/app/src/main/java/fr/ynerant/tarot/ui/newgame/NewGameFragment.java b/app/src/main/java/fr/ynerant/tarot/ui/newgame/NewGameFragment.java index 0dd6963..60a2472 100644 --- a/app/src/main/java/fr/ynerant/tarot/ui/newgame/NewGameFragment.java +++ b/app/src/main/java/fr/ynerant/tarot/ui/newgame/NewGameFragment.java @@ -5,23 +5,30 @@ import android.preference.PreferenceManager; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.Button; +import android.widget.CompoundButton; import android.widget.LinearLayout; import android.widget.SeekBar; import android.widget.Spinner; -import android.widget.SpinnerAdapter; import android.widget.Switch; import android.widget.TextView; import android.widget.Toast; +import android.widget.ToggleButton; import androidx.annotation.NonNull; import androidx.fragment.app.Fragment; import androidx.lifecycle.ViewModelProviders; +import org.apache.commons.io.IOUtils; + +import java.io.IOException; +import java.net.HttpURLConnection; +import java.net.URL; import java.util.ArrayList; -import java.util.HashSet; -import java.util.Locale; +import java.util.List; +import java.util.concurrent.Executors; import fr.ynerant.tarot.Game; import fr.ynerant.tarot.MainActivity; @@ -59,17 +66,28 @@ public class NewGameFragment extends Fragment { final LinearLayout player5_layout = root.findViewById(R.id.player5_layout); final LinearLayout player6_layout = root.findViewById(R.id.player6_layout); + final List players = new ArrayList<>(); + //noinspection ConstantConditions ArrayAdapter adapter = new ArrayAdapter<>(getContext(), android.R.layout.simple_spinner_item, new ArrayList<>(Player.getAllPlayers())); adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); player1.setAdapter(adapter); player2.setAdapter(adapter); + player2.setSelection(1); player3.setAdapter(adapter); + player3.setSelection(2); player4.setAdapter(adapter); + player4.setSelection(3); player5.setAdapter(adapter); + player5.setSelection(4); player6.setAdapter(adapter); + player6.setSelection(5); final Spinner[] spinners = new Spinner[]{player1, player2, player3, player4, player5, player6}; + final Spinner attacker = root.findViewById(R.id.attacker); + final Spinner follower = root.findViewById(R.id.follower); + final LinearLayout follower_layout = root.findViewById(R.id.follower_layout); + final Spinner dealer = root.findViewById(R.id.dealer); final SeekBar attack_points = root.findViewById(R.id.attack_score); final SeekBar bet = root.findViewById(R.id.bet); final SeekBar nb_ends = root.findViewById(R.id.nb_ends); @@ -77,32 +95,143 @@ public class NewGameFragment extends Fragment { final Switch chelem_realized = root.findViewById(R.id.chelem_realized); final SeekBar little_end = root.findViewById(R.id.little_end); final SeekBar handle = root.findViewById(R.id.handle); + final ToggleButton misery1 = root.findViewById(R.id.player1_misery); + final ToggleButton misery2 = root.findViewById(R.id.player2_misery); + final ToggleButton misery3 = root.findViewById(R.id.player3_misery); + final ToggleButton misery4 = root.findViewById(R.id.player4_misery); + final ToggleButton misery5 = root.findViewById(R.id.player5_misery); + final ToggleButton misery6 = root.findViewById(R.id.player6_misery); + final ToggleButton[] miseries = new ToggleButton[]{misery1, misery2, misery3, misery4, misery5, misery6}; + final TextView misery1Text = root.findViewById(R.id.player1_misery_text); + final TextView misery2Text = root.findViewById(R.id.player2_misery_text); + final TextView misery3Text = root.findViewById(R.id.player3_misery_text); + final TextView misery4Text = root.findViewById(R.id.player4_misery_text); + final TextView misery5Text = root.findViewById(R.id.player5_misery_text); + final TextView misery6Text = root.findViewById(R.id.player6_misery_text); + final TextView points1 = root.findViewById(R.id.player1_points); + final TextView points2 = root.findViewById(R.id.player2_points); + final TextView points3 = root.findViewById(R.id.player3_points); + final TextView points4 = root.findViewById(R.id.player4_points); + final TextView points5 = root.findViewById(R.id.player5_points); + final TextView points6 = root.findViewById(R.id.player6_points); + final TextView[] points = new TextView[]{points1, points2, points3, points4, points5, points6}; + final TextView points1Text = root.findViewById(R.id.player1_points_text); + final TextView points2Text = root.findViewById(R.id.player2_points_text); + final TextView points3Text = root.findViewById(R.id.player3_points_text); + final TextView points4Text = root.findViewById(R.id.player4_points_text); + final TextView points5Text = root.findViewById(R.id.player5_points_text); + final TextView points6Text = root.findViewById(R.id.player6_points_text); final Runnable updateScore = new Runnable() { @Override public void run() { - TextView textView = root.findViewById(R.id.nb_points); - Game game = new Game(); - game.attackScore = attack_points.getProgress(); - game.type = Game.GameType.getGameType(nb_players.getProgress() + 3); - game.players = new HashSet<>(); - for (int i = 0; i < 3 + nb_players.getProgress(); ++i) { - game.players.add((Player) spinners[i].getSelectedItem()); + Game game = getGame(); + + for (int i = 0; i < game.getGameType().getNbPlayers(); ++i) { + points[i].setText(String.valueOf(game.points.get(i))); } + } + + public Game getGame() { + Game game = new Game(); + game.gameType = Game.GameType.getGameType(nb_players.getProgress() + 3); + game.attacker = (Player) attacker.getSelectedItem(); + if (game.getGameType().getNbPlayers() >= 5) + game.follower = (Player) follower.getSelectedItem(); + game.attackScore = attack_points.getProgress(); + game.players = players; game.bet = Game.Bet.values()[bet.getProgress()]; game.ends = nb_ends.getProgress(); + game.handle = handle.getProgress(); game.chelemAnnounced = chelem_announced.isChecked(); game.chelemRealized = chelem_realized.isChecked(); game.littleForAttacker = little_end.getProgress() == 1; game.littleForDefenser = little_end.getProgress() == 2; - game.handle = handle.getProgress(); + List miseriesList = new ArrayList<>(); + for (int i = 0; i < game.getGameType().getNbPlayers(); ++i) + miseriesList.add(miseries[i].isChecked()); + game.miseries = miseriesList; + game.calculateScores(); - - textView.setText(String.format(Locale.getDefault(), "%d points (hors misères)", game.calculateScore())); + return game; } }; - updateScore.run(); + final Spinner.OnItemSelectedListener updatePlayers = new Spinner.OnItemSelectedListener() { + @Override + public void onItemSelected(AdapterView parent, View view, int position, long id) { + players.clear(); + players.add((Player) player1.getSelectedItem()); + players.add((Player) player2.getSelectedItem()); + players.add((Player) player3.getSelectedItem()); + if (nb_players.getProgress() >= 1) + players.add((Player) player4.getSelectedItem()); + if (nb_players.getProgress() >= 2) + players.add((Player) player5.getSelectedItem()); + if (nb_players.getProgress() == 3) + players.add((Player) player6.getSelectedItem()); + + //noinspection ConstantConditions + ArrayAdapter adapter = new ArrayAdapter<>(getContext(), android.R.layout.simple_spinner_item, new ArrayList<>(players)); + adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); + attacker.setAdapter(adapter); + dealer.setAdapter(adapter); + follower.setAdapter(adapter); + + misery1Text.setText(((Player) player1.getSelectedItem()).getName()); + misery2Text.setText(((Player) player2.getSelectedItem()).getName()); + misery3Text.setText(((Player) player3.getSelectedItem()).getName()); + misery4Text.setText(((Player) player4.getSelectedItem()).getName()); + misery5Text.setText(((Player) player5.getSelectedItem()).getName()); + misery6Text.setText(((Player) player6.getSelectedItem()).getName()); + points1Text.setText(((Player) player1.getSelectedItem()).getName()); + points2Text.setText(((Player) player2.getSelectedItem()).getName()); + points3Text.setText(((Player) player3.getSelectedItem()).getName()); + points4Text.setText(((Player) player4.getSelectedItem()).getName()); + points5Text.setText(((Player) player5.getSelectedItem()).getName()); + points6Text.setText(((Player) player6.getSelectedItem()).getName()); + + updateScore.run(); + } + + @Override + public void onNothingSelected(AdapterView parent) {} + }; + + Spinner.OnItemSelectedListener justUpdate = new Spinner.OnItemSelectedListener() { + @Override + public void onItemSelected(AdapterView parent, View view, int position, long id) { + updateScore.run(); + } + + @Override + public void onNothingSelected(AdapterView parent) { + } + }; + + ToggleButton.OnCheckedChangeListener justUpdate2 = new ToggleButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + updateScore.run(); + } + }; + + updatePlayers.onItemSelected(null, null, 0, 0); + player1.setOnItemSelectedListener(updatePlayers); + player2.setOnItemSelectedListener(updatePlayers); + player3.setOnItemSelectedListener(updatePlayers); + player4.setOnItemSelectedListener(updatePlayers); + player5.setOnItemSelectedListener(updatePlayers); + player6.setOnItemSelectedListener(updatePlayers); + attacker.setOnItemSelectedListener(justUpdate); + follower.setOnItemSelectedListener(justUpdate); + dealer.setOnItemSelectedListener(justUpdate); + misery1.setOnCheckedChangeListener(justUpdate2); + misery2.setOnCheckedChangeListener(justUpdate2); + misery3.setOnCheckedChangeListener(justUpdate2); + misery4.setOnCheckedChangeListener(justUpdate2); + misery5.setOnCheckedChangeListener(justUpdate2); + misery6.setOnCheckedChangeListener(justUpdate2); nb_players.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { @Override @@ -126,17 +255,47 @@ public class NewGameFragment extends Fragment { nb_players_info.setText(resource); player4_layout.setVisibility(View.GONE); + misery4Text.setVisibility(View.GONE); + misery4.setVisibility(View.GONE); + points4Text.setVisibility(View.GONE); + points4.setVisibility(View.GONE); player5_layout.setVisibility(View.GONE); + misery5Text.setVisibility(View.GONE); + misery5.setVisibility(View.GONE); + points5Text.setVisibility(View.GONE); + points5.setVisibility(View.GONE); player6_layout.setVisibility(View.GONE); + misery6Text.setVisibility(View.GONE); + misery6.setVisibility(View.GONE); + points6Text.setVisibility(View.GONE); + points6.setVisibility(View.GONE); + follower_layout.setVisibility(View.GONE); switch (progress + 3) { case 6: player6_layout.setVisibility(View.VISIBLE); + misery6Text.setVisibility(View.VISIBLE); + misery6.setVisibility(View.VISIBLE); + points6Text.setVisibility(View.VISIBLE); + points6.setVisibility(View.VISIBLE); case 5: player5_layout.setVisibility(View.VISIBLE); + misery5Text.setVisibility(View.VISIBLE); + misery5.setVisibility(View.VISIBLE); + points5Text.setVisibility(View.VISIBLE); + points5.setVisibility(View.VISIBLE); + follower_layout.setVisibility(View.VISIBLE); case 4: player4_layout.setVisibility(View.VISIBLE); + misery4Text.setVisibility(View.VISIBLE); + misery4.setVisibility(View.VISIBLE); + points4Text.setVisibility(View.VISIBLE); + points4.setVisibility(View.VISIBLE); + } + + updatePlayers.onItemSelected(null, null, 0, 0); + updateScore.run(); } @Override @@ -314,7 +473,52 @@ public class NewGameFragment extends Fragment { btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - Toast.makeText(getContext(), "La partie sera sauvegardée ultérieurement.", Toast.LENGTH_SHORT).show(); + Toast.makeText(getContext(), "La partie est enregistrée !", Toast.LENGTH_SHORT).show(); + Executors.newSingleThreadExecutor().execute(new Runnable() { + @Override + public void run() { + Game g = getGame(); + + try { + URL url = new URL("https://galaxyoyo.com/tarot/game.php?add_game"); + HttpURLConnection co = (HttpURLConnection) url.openConnection(); + co.setRequestMethod("POST"); + co.setRequestProperty("token", PreferenceManager.getDefaultSharedPreferences(MainActivity.INSTANCE).getString("token", null)); + co.setRequestProperty("json", g.toJson()); + co.connect(); + System.out.println(g.toJson()); + System.err.println(IOUtils.readLines(co.getInputStream())); + co.disconnect(); + } catch (IOException ex) { + ex.printStackTrace(); + } + } + }); + + } + + public Game getGame() { + Game game = new Game(); + game.gameType = Game.GameType.getGameType(nb_players.getProgress() + 3); + game.attacker = (Player) attacker.getSelectedItem(); + if (game.getGameType().getNbPlayers() >= 5) + game.follower = (Player) follower.getSelectedItem(); + game.attackScore = attack_points.getProgress(); + game.players = players; + game.bet = Game.Bet.values()[bet.getProgress()]; + game.ends = nb_ends.getProgress(); + game.handle = handle.getProgress(); + game.chelemAnnounced = chelem_announced.isChecked(); + game.chelemRealized = chelem_realized.isChecked(); + game.littleForAttacker = little_end.getProgress() == 1; + game.littleForDefenser = little_end.getProgress() == 2; + List miseriesList = new ArrayList<>(); + for (int i = 0; i < game.getGameType().getNbPlayers(); ++i) + miseriesList.add(miseries[i].isChecked()); + game.miseries = miseriesList; + game.calculateScores(); + + return game; } }); diff --git a/app/src/main/res/layout/fragment_new_game.xml b/app/src/main/res/layout/fragment_new_game.xml index 39fa84c..8a92e5f 100644 --- a/app/src/main/res/layout/fragment_new_game.xml +++ b/app/src/main/res/layout/fragment_new_game.xml @@ -167,6 +167,23 @@ android:layout_height="wrap_content" /> + + + + + + + @@ -426,18 +442,192 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +