Strategy 인터페이스
package kch;
public interface Strategy {
public abstract Hand nextHand();
public abstract void study(booleanwin);
}
WinningStrategy 클래스
package kch;
import java.util.Random;
public class WinningStrategy implementsStrategy{
//이 클래스는 전판이 이기면 다음에도똑같은 것을 내는 전략을 취함
privateRandom random;//랜덤변수 생성 목적
private boolean won = false;//전판이 이겼는지 졌는지에 대한 필드
private HandprevHand;//전판에 내밀었던 손을 저장함
publicWinningStrategy(int seed){
random = new Random(seed);
}
public HandnextHand(){
if(!won){//만약에지면 랜덤으로 만듬 0,1,2의 값중에 하나가 나옴
prevHand =Hand.getHand(random.nextInt(3));//
}
returnprevHand;//이겼다면 똑같은 손을 내밀게 됨.
}
public void study(boolean win){
won = win;//
}
}
ProbStrategy 클래스
package kch;
import java.util.Random;
public class ProbStrategy implementsStrategy{
privateRandom random;
private int prevHandValue = 0;
private int currentHandValue = 0;
private int[][] history = {
{1,1,1,},
{1,1,1,},
{1,1,1,},
};
//[0][1] 이면 0이니까 이전에 주먹을 내고 이번에 가위를 냈을 때의 과거의 승수
//[0][2] 이면 이전에 주먹을 내고 이번에보를 냈을때의 과거의 승수
publicProbStrategy(int seed){
random = new Random(seed);
}
public HandnextHand(){
int bet= random.nextInt(getSum(currentHandValue));//랜덤변수 발생
//이때 getSum을 쓰는데
//history[0][0] 값이 3
//history[0][1] 값이 5
//history[0][2] 값이 7
//이면 주먹:가위:보 = 3:5:7로계산에 의한 난수값을 얻는다
//즉 3/15의 확률로 주먹이 나오고 5/15로 가위 7/15로 보자기가 나오게 된다.
inthandvalue = 0;
//위에서 설명한 부분을 실제로고르는 부분 다음에 낼 손을 고른다.
if(bet< history[currentHandValue][0]){
handvalue = 0;
}
else if(bet < history[currentHandValue][0] +history[currentHandValue][1]){
handvalue = 1;
}else{
handvalue = 2;
}
prevHandValue = currentHandValue;//현재 낸것은
currentHandValue = handvalue;
returnHand.getHand(handvalue);
}
private int getSum(int hv){
int sum= 0;
for(int i = 0; i < 3; i++){
sum += history[hv][i];
}
//리턴값은 [주먹][가위] + [주먹][보자기] + [주먹][주먹] 에 대한 합 값
return sum;
}
public void study(boolean win){
if(win){//이기면그때의 값이 올라감
history[prevHandValue][currentHandValue]++;
} else {
//지거나 비기면 다른 경우의 수가 올라감
history[prevHandValue][(currentHandValue+ 1) % 3 ]++;
history[prevHandValue][(currentHandValue+ 2) % 3 ]++;
}
}
}
Hand 클래스
package kch;
public class Hand {
public static final int HANDVALUE_MUK = 0;
public static final int HANDVALUE_JJI = 1;
public static final int HANDVALUE_BBA = 2;
public static final Hand[] hand = {
newHand(HANDVALUE_MUK),
newHand(HANDVALUE_JJI),
newHand(HANDVALUE_BBA)
};
private static final String[] name = {
"주먹", "가위", "보"
};
private int handvalue;
privateHand(int handvalue){
this.handvalue= handvalue;
}
public static Hand getHand(inthandvalue){
returnhand[handvalue];
}
public boolean isStrongerThan(Hand h){//this가 h 를 이길경우 true
returnfight(h) == 1;
}
public boolean isWeakerThan(Hand h){//this가 h에게 질 경우true
returnfight(h) == -1;
}
private int fight(Hand h){
if(this == h){//무승부면
return 0;
}else if((this.handvalue + 1) % 3 == h.handvalue){//this의 승
return 1;
}else{//this의 패
return -1;
}
}
publicString toString(){//문자열 표현으로 변환
returnname[handvalue];
}
}
Player 클래스
package kch;
public class Player {
privateString name;
privateStrategy strategy;
private int wincount;
private int losecount;
private int gamecount;
publicPlayer(String name, Strategy strategy){
this.name = name;
this.strategy = strategy;
}
public HandnextHand(){
return strategy.nextHand();
}
public void win(){
strategy.study(true);//넘기는 값은 현재 게임이 이겼는지 졌는지
wincount++;
gamecount++;
}
public void lose(){
strategy.study(false);//넘기는 값은 현재 게임이 이겼는지 졌는지
losecount++;
gamecount++;
}
public void even(){
gamecount++;
}
publicString toString(){
return "[" + name + ":" +gamecount + "games," + wincount + "win, " + losecount +
" lose" + "]";
}
}
Main 클래스
package kch;
public class Main {
public static void main(String [] args){
if(args.length != 2){
System.out.println("error.input the 2 parameter");
System.exit(0);
}
intseed1 = Integer.parseInt(args[0]);
intseed2 = Integer.parseInt(args[1]);
Player player1 = new Player("두리", new WinningStrategy(seed1));
//두리는 WinningStrategy 전략을 씀.
Player player2 = new Player("하나", new ProbStrategy(seed2));
//하나는 ProbStrategy 전략을 씀.
for(int i = 0; i < 10000; i++){//만번 돌림
Hand nextHand1 =player1.nextHand();//다음 손을 냄.
Hand nextHand2 =player2.nextHand();//다음 손을 냄.
if(nextHand1.isStrongerThan(nextHand2)){//비교함
//player1 이길때
System.out.println("Winner:" + player1);
player1.win();
player2.lose();
}
else if(nextHand2.isStrongerThan(nextHand1)){
//player2 질때
System.out.println("Winner:" + player2);
player1.lose();
player2.win();
}
else{
//비길때.
System.out.println("Even..");
player1.even();
player2.even();
}
}
System.out.println("Totalresult: ");
System.out.println(player1.toString());//미리 정의한 글자가 나옴,
System.out.println(player2.toString());
}
}
이러한 전략 패턴은
메모리가 적은 환경에서는 메모리 필요가 적은 클래스를 사용하고 많을 때는 메모리가 많이 소비되는 클래스를 사용하는여러 전략을 둘 수 있게합니다.
즉 그때그때 맞춰나갈 수 있다는 것이 장점입니다.
'프로그래밍 > 자바 디자인패턴' 카테고리의 다른 글
디자인 패턴 위임에 의한 Adapter 패턴(인스턴스를 이용한) (0) | 2012.08.03 |
---|---|
디자인 패턴 Adapter패턴 상속을 사용한 Adapter패턴 (0) | 2012.08.03 |
디자인패턴 Chain of Responsibility 패턴 (0) | 2012.08.02 |
디자인 패턴 Visitor 패턴 (0) | 2012.08.01 |
디자인 패턴 Decorator 패턴 (0) | 2012.08.01 |
디자인 패턴 Composite 패턴 (0) | 2012.08.01 |
디자인 패턴 Bridge 패턴 (0) | 2012.08.01 |
디자인 패턴 Builder 패턴 (1) | 2012.08.01 |