Skip to contentMethod: hashCode()
1: /*
2: * Copyright © 2021-2022 Fachhochschule für die Wirtschaft (FHDW) Hannover
3: *
4: * This file is part of ipspiel22-demo.
5: *
6: * Ipspiel22-demo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public
7: * License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later
8: * version.
9: *
10: * Ipspiel22-demo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
11: * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12: *
13: * You should have received a copy of the GNU General Public License along with ipspiel22-demo. If not, see
14: * <http://www.gnu.org/licenses/>.
15: */
16: package de.fhdw.gaming.core.domain;
17:
18: import java.util.Objects;
19: import java.util.Optional;
20:
21: /**
22: * A foundation block for implementing players.
23: *
24: * @param <P> The type of allowed players.
25: */
26: public abstract class AbstractPlayer<P extends Player<P>> implements Player<P> {
27:
28: /**
29: * The name of this player.
30: */
31: private final String name;
32: /**
33: * The state of the player.
34: */
35: private PlayerState state;
36: /**
37: * The outcome of the player.
38: */
39: private Optional<Double> outcome;
40:
41: /**
42: * Creates a player.
43: *
44: * @param name The name of the player.
45: */
46: protected AbstractPlayer(final String name) {
47: this.name = Objects.requireNonNull(name, "name");
48: this.state = PlayerState.PLAYING;
49: this.outcome = Optional.empty();
50: }
51:
52: /**
53: * Creates a Demo player.
54: *
55: * @param source The {@link Player} to copy.
56: */
57: protected AbstractPlayer(final P source) {
58: this.name = source.getName();
59: this.state = source.getState();
60: this.outcome = source.getOutcome();
61: }
62:
63: @Override
64: public boolean equals(final Object obj) {
65: if (obj instanceof AbstractPlayer) {
66: final AbstractPlayer<?> other = (AbstractPlayer<?>) obj;
67: return this.name.equals(other.name) && this.state.equals(other.state)
68: && this.outcome.equals(other.outcome);
69: }
70: return false;
71: }
72:
73: @Override
74: public int hashCode() {
75: return this.name.hashCode();
76: }
77:
78: @Override
79: public final String getName() {
80: return this.name;
81: }
82:
83: @Override
84: public final PlayerState getState() {
85: return this.state;
86: }
87:
88: @Override
89: public final void setState(final PlayerState newState) {
90: this.state = newState;
91: if (newState.equals(PlayerState.PLAYING)) {
92: this.outcome = Optional.empty();
93: }
94: }
95:
96: @Override
97: public final Optional<Double> getOutcome() {
98: return this.outcome.isPresent() ? this.outcome : mapStateToOutcome(this.state);
99: }
100:
101: @Override
102: public final void setOutcome(final double newOutcome) {
103: if (this.state.equals(PlayerState.PLAYING)) {
104: throw new IllegalStateException(String.format("Cannot set outcome for player %s.", this.name));
105: }
106: this.outcome = Optional.of(newOutcome);
107: }
108:
109: /**
110: * Maps passed player state to the player's outcome. The outcome is unavailable
111: * if the state is {@link PlayerState#PLAYING}. Otherwise, the outcome is computed from the player
112: * state as follows:
113: * <ul>
114: * <li>1.0 if the state is {@link PlayerState#WON}</li>
115: * <li>0.0 if the state is {@link PlayerState#DRAW}</li>
116: * <li>-1.0 if the state is {@link PlayerState#LOST} or
117: * {@link PlayerState#RESIGNED}</li>
118: * </ul>
119: *
120: * @param state The player state.
121: */
122: public static Optional<Double> mapStateToOutcome(final PlayerState state) {
123: switch (state) {
124: case WON:
125: return Optional.of(1.0);
126: case LOST:
127: case RESIGNED:
128: return Optional.of(-1.0);
129: case DRAW:
130: return Optional.of(0.0);
131: case PLAYING:
132: default:
133: return Optional.empty();
134: }
135: }
136: }