Tested and implemented scoring

git-svn-id: svn://sunsvr01.isp.uni-luebeck.de/swproj13/trunk@272 72836036-5685-4462-b002-a69064685172
This commit is contained in:
Jannis Harder 2011-05-25 15:51:34 +02:00
parent e3b5a0790d
commit 157bd4f606
8 changed files with 283 additions and 29 deletions

View file

@ -7,8 +7,10 @@ import jrummikub.model.GameSettings;
import jrummikub.model.GameState;
import jrummikub.model.IRoundState;
import jrummikub.model.RoundState;
import jrummikub.model.Score;
import jrummikub.util.Connection;
import jrummikub.util.IListener;
import jrummikub.util.IListener1;
import jrummikub.view.IView;
/**
@ -68,10 +70,10 @@ public class GameControl {
roundState.setActivePlayerNumber(gameState.getFirstRoundFirstPlayer());
roundControl = new RoundControl(roundState, view);
roundControl.getEndOfRoundEvent().add(new IListener() {
roundControl.getEndOfRoundEvent().add(new IListener1<Score>() {
@Override
public void handle() {
public void handle(Score roundScore) {
endOfRound();
}
});

View file

@ -6,15 +6,17 @@ import java.util.List;
import java.util.Set;
import jrummikub.model.Hand;
import jrummikub.model.IRoundState;
import jrummikub.model.IHand;
import jrummikub.model.IPlayer;
import jrummikub.model.IRoundState;
import jrummikub.model.ITable;
import jrummikub.model.Position;
import jrummikub.model.Score;
import jrummikub.model.Stone;
import jrummikub.model.StoneSet;
import jrummikub.util.Connection;
import jrummikub.util.Event;
import jrummikub.util.IEvent;
import jrummikub.util.Event1;
import jrummikub.util.IEvent1;
import jrummikub.util.IListener;
import jrummikub.util.Pair;
import jrummikub.view.IView;
@ -26,7 +28,7 @@ public class RoundControl {
private IRoundState roundState;
private IView view;
private ITable clonedTable;
private Event endOfRoundEvent = new Event();
private Event1<Score> endOfRoundEvent = new Event1<Score>();
private List<Connection> connections = new ArrayList<Connection>();
private boolean roundFinished;
@ -48,7 +50,7 @@ public class RoundControl {
*
* @return endOfRoundEvent
*/
public IEvent getEndOfRoundEvent() {
public IEvent1<Score> getEndOfRoundEvent() {
return endOfRoundEvent;
}
@ -134,7 +136,6 @@ public class RoundControl {
}
} else {
if (roundState.getActivePlayer() == roundState.getLastPlayer()) {
// TODO check who has won
endOfRound();
} else {
roundState.nextPlayer();
@ -237,11 +238,65 @@ public class RoundControl {
dealStones(count + 3);
}
private void endOfRound() {
void endOfRound() {
for (Connection c : connections) {
c.remove();
}
endOfRoundEvent.emit();
Score roundScore = score();
endOfRoundEvent.emit(roundScore);
roundFinished = true;
}
private Score score() {
List<Boolean> winners = new ArrayList<Boolean>();
List<Integer> points = new ArrayList<Integer>();
boolean foundRegularWinner = false;
int winnerPlayerNumber = 0;
Pair<Integer, Integer> bestScore = new Pair<Integer, Integer>(Integer.MIN_VALUE, Integer.MAX_VALUE);
int pointSum = 0;
for (int i = 0; i < roundState.getPlayerCount(); i++) {
IPlayer player = roundState.getNthPlayer(i);
IHand playerHand = player.getHand();
boolean isWinner = playerHand.getSize() == 0;
winners.add(isWinner);
if (isWinner) {
foundRegularWinner = true;
winnerPlayerNumber = i;
}
int stonePoints = 0;
if (!player.getLaidOut()) {
stonePoints = playerHand.isInitialMeldPossible() ? 200 : 100;
} else {
stonePoints = playerHand.getStonePoints();
}
bestScore = updateBestScore(bestScore, -stonePoints, playerHand.getSize());
points.add(-stonePoints);
pointSum += stonePoints;
}
if (foundRegularWinner) {
points.set(winnerPlayerNumber, pointSum);
} else {
for (int i = 0; i < roundState.getPlayerCount(); i++) {
if (bestScore.equals(new Pair<Integer, Integer>(points.get(i), roundState.getNthPlayer(i).getHand().getSize()))) {
winners.set(i, true);
}
}
}
return new Score(winners, points);
}
private static Pair<Integer, Integer> updateBestScore(
Pair<Integer, Integer> bestScore, int stonePoints, int size) {
if (bestScore.getFirst() == stonePoints) {
return new Pair<Integer, Integer>(stonePoints, Math.min(bestScore.getSecond(), size));
} else if (bestScore.getFirst() < stonePoints) {
return new Pair<Integer, Integer>(stonePoints, size);
}
return bestScore;
}
}

View file

@ -60,6 +60,15 @@ public interface IRoundState {
*/
public IPlayer getNthNextPlayer(int i);
/**
* Returns the nth player
*
* @param i
* player number
* @return nth player
*/
public IPlayer getNthPlayer(int i);
/**
* Sets the player that will make the last turn before the round ends when
* the heap is empty

View file

@ -70,6 +70,15 @@ public class RoundState implements IRoundState {
}
return players.get(j);
}
@Override
public IPlayer getNthPlayer(int i) {
int j = i % players.size();
if (j < 0) {
j += players.size();
}
return players.get(j);
}
@Override
public IPlayer getActivePlayer() {

View file

@ -0,0 +1,42 @@
package jrummikub.model;
import java.util.List;
/**
* Score of a single round
*/
public class Score {
List<Boolean> winners;
List<Integer> points;
/**
* Create a new round score
*
* @param winners
* set for each player among the winners
* @param points
* points of each player
*/
public Score(List<Boolean> winners, List<Integer> points) {
this.winners = winners;
this.points = points;
}
/**
* Get the winner list
*
* @return set for each player among the winners
*/
public List<Boolean> getWinners() {
return winners;
}
/**
* Get the point list
*
* @return points of each player
*/
public List<Integer> getPoints() {
return points;
}
}

View file

@ -48,4 +48,35 @@ public class Pair<T1, T2> {
return "Pair [first=" + first + ", second=" + second + "]";
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((first == null) ? 0 : first.hashCode());
result = prime * result + ((second == null) ? 0 : second.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Pair other = (Pair) obj;
if (first == null) {
if (other.first != null)
return false;
} else if (!first.equals(other.first))
return false;
if (second == null) {
if (other.second != null)
return false;
} else if (!second.equals(other.second))
return false;
return true;
}
}