실행코드 ¶
~cpp code
import javax.swing.JOptionPane;
public class BaseBall {
private int correctNumber;
public static void main(String[] args) {
BaseBall oneGame = new BaseBall();
oneGame.setCorrectNumber();
int guess = 0, result = 0;
do
{
guess = oneGame.inputGuess();
result = oneGame.compare(guess);
if (result != 30)
JOptionPane.showMessageDialog(null, (result / 10) + " Strike, "
+ (result % 10) + " Ball");
}while (result != 30);
oneGame.displayResult();
}
public void setCorrectNumber()
{
int setNumber = 0;
do
{
setNumber = (int) (Math.random() * 10);
}while (setNumber == 0);
correctNumber = setNumber;
do
{
setNumber = (int) (Math.random() * 10);
}while (correctNumber == setNumber);
correctNumber = correctNumber * 10 + setNumber;
do
{
setNumber = (int) (Math.random() * 10);
}while (((int)(correctNumber / 10)) == setNumber
|| ((int)(correctNumber % 10)) == setNumber);
correctNumber = correctNumber * 10 + setNumber;
}
public int inputGuess()
{
String input = JOptionPane.showInputDialog("Enter three different number\n");
int guess = Integer.parseInt(input);
return guess;
}
public int compare(int aGuess)
{
int compareResult = 0, cCorrect = correctNumber;
int firstGuess = (int) (aGuess / 100);
int secondGuess = ((int) (aGuess / 10)) % 10;
int thirdGuess = aGuess % 10;
if (((int)(cCorrect / 100) == firstGuess))
compareResult ++;
cCorrect = cCorrect % 100;
if (((int)(cCorrect / 10) == secondGuess))
compareResult ++;
cCorrect = cCorrect % 10;
if (cCorrect == thirdGuess)
compareResult ++;
compareResult *= 10;
cCorrect = correctNumber;
if (((int)(cCorrect / 100)) == secondGuess
|| ((int)(cCorrect / (100))) == thirdGuess)
compareResult ++;
cCorrect = cCorrect % 100;
if (((int)(cCorrect / 10)) == firstGuess
|| ((int)(cCorrect / (10))) == thirdGuess)
compareResult ++;
cCorrect = cCorrect % 10;
if ((cCorrect == firstGuess) || (cCorrect == secondGuess))
compareResult ++;
return compareResult;
}
public void displayResult()
{
JOptionPane.showMessageDialog(null, "You are right!\n Answer is " + correctNumber);
}
}
잡담 ¶
- ì •ë‹µì�„ int변수 3ìž�리 숫ìž�로 표현해서 만들어봤ë�”니 코드만 ë�” 길어졌네요 -0-;; - 문ì›�명
ê°œì„ ì‹œë�„ ¶
ì§‘ì—�서 놀다가 우연히 여기를 와서 ê³ ì³�봅니다. 조금 ë�” ìƒ�ê°�í•´ 보시면 ë�˜ì§€ìš”. ì €ì—�게 재미있는 경험ì�„ 주었는ë�°, 문ì›�명 후배님ë�„ 보시ë�¼ê³ ê³¼ì •ì�„ 만들어 ë‘�었습니다. ì„ í–‰í•™ìŠµìœ¼ë¡œ JUnitì�´ 있어야 하는ë�°, http://junit.org ì—�서 ê¶�금하시면 ê´€ë ¨ë¬¸ì„œë¥¼ ë³´ì‹œê³ ì„ ë°°ë“¤ì—�게 물어보세요.
용기가 내셔서 ì €ë¥¼ 찾으면...
--NeoCoin
--NeoCoin
- 처ì�Œì—�는 Test-Driven Development ì—� ìž…ê°�하여 만들어 ë³´ë ¤ê³ í–ˆìœ¼ë‚˜, Java를 ê±°ì�˜ 처ì�Œ ì‹œìž‘í•˜ê³ í”„ë¡œê·¸ëž˜ë°� 경험ì�˜ 공백기간ì�´ 길었ë�˜ê²Œ í�° 타격ì�´ì—ˆìŠµë‹ˆë‹¤ã… ã… . ê²°êµì—�는 문법과 ì•Œê³ ë¦¬ì¦˜ì—�ë§Œ ì‹ ê²½ì�„ 쓰다보니 TDDë°©ì‹�으로 다루기가 쉽지 않네요. ê°œì„ ì¡°ì–¸ì�„ í•´ ì£¼ì‹ ë¥˜ìƒ�민 ì„ ë°°ë‹˜ ê°�사합니다 ã…Žã…Ž -문ì›�명
- 오해가 있ì�„ 것 같아서 코멘트 합니다. TDD는 별로 중요하지 않습니다. ê²°ì •ì �으로 ì €ëŠ” TDD로 하지 않았습니다. 그냥 Refactoring시 Regression Test를 위해서 JUnit ì�„ ì�¼ì�„ ë¿�ì�´ì—�ìš”.--NeoCoin
- 네, ì œê°€ TDDì�˜ ì�˜ë¯¸ë¥¼ 확실히 하지 못한 것 같습니다. TDDì±…ì�˜ 앞부분만 ì�½ì–´ 보았는ë�°, 계ì†�해서 ë�” ì�½ì–´ì•¼ ë‚˜ê°€ì•¼ê² ë‹¤ëŠ” 다ì§�ì�´ 드네요. 관심 ê°€ì ¸ì£¼ì…”ì„œ ê³ ë§™ìŠµë‹ˆë‹¤ ã…‹ -문ì›�명
- 네, ì œê°€ TDDì�˜ ì�˜ë¯¸ë¥¼ 확실히 하지 못한 것 같습니다. TDDì±…ì�˜ 앞부분만 ì�½ì–´ 보았는ë�°, 계ì†�해서 ë�” ì�½ì–´ì•¼ ë‚˜ê°€ì•¼ê² ë‹¤ëŠ” 다ì§�ì�´ 드네요. 관심 ê°€ì ¸ì£¼ì…”ì„œ ê³ ë§™ìŠµë‹ˆë‹¤ ã…‹ -문ì›�명
- 오해가 있ì�„ 것 같아서 코멘트 합니다. TDD는 별로 중요하지 않습니다. ê²°ì •ì �으로 ì €ëŠ” TDD로 하지 않았습니다. 그냥 Refactoring시 Regression Test를 위해서 JUnit ì�„ ì�¼ì�„ ë¿�ì�´ì—�ìš”.--NeoCoin
ê³¼ì • ¶
초기� 테스트 가능하�� �하는 값으로 무작위로 나오는 답안� 세팅하는 함수 추가.
setCorrectNumber 하기ë�„ 귀찮아서 compare 부분ì�„ 확장 , ë‚´ë¶€ì—�서 ì“°ì�¼ì�¼ì�´ 없는 함수로 ì œê±° 목ì �으로 코스 ìˆ˜ì •
readability 를 위해 필요없는 typecasting 문법들 ì œê±° (Java Language Specificationì�˜ 규칙들ì�„ 보세요. 해당 typecastingì�€ ê±°ì�˜ë‹¤ í•„ìš” 없는ê²�니다.) ìœ ì�˜ë¯¸í•œ 단위로 분리
해당 함수를 ì•Œê³ ë¦¬ì¦˜ì—� ì �ìš©, Test는 계ì†� 녹색 .
결과 값� �미를 드러낼수 있�� 변경
ë�”ì�´ìƒ� 함수가 this.correctNumberì—� ì�˜ì¡´í• í•„ìš” 없으므로 코드 ê°œì„
숫ìž� 패턴ì�„ íŒŒì•…í•˜ê³ ì¤‘ë³µ ê°œì„ , magic number ì œê±°
ë‘�ê°œì�˜ 루프ì�˜ ì •í™•í•œ ì�˜ë¯¸ 파악, 합침
해당 루틴ì�´ ì§€ë‚ ë•Œ 마다 result ê°’ì—� 10ê³¼ 1ì�„ ë�”해주는 ë°©ì‹�으로 바꿈
기타 overloadingë�œ 무ì�˜ë¯¸í•œ compare를 ì •ë¦¬. 소스ìƒ� setCorrectNumber를 ìƒ�성ìž�로 옮김.
ë�” ê°œì„ í•˜ê³ ì‹¶ìœ¼ë‚˜ 그냥 하기 ì§€ì³�서 여기서 그만..
~java
// ..�략
void setCorrectNumber(int in) {
correctNumber = in;
}
@Test
public void test2() {
BaseBall oneGame = new BaseBall();
oneGame.setCorrectNumber(123);
assertEquals(30, oneGame.compare(123));
assertEquals(10, oneGame.compare(100, 123));
assertEquals(2, oneGame.compare(310, 123));
}
//..�략
~java
@Test
public void test2() {
BaseBall oneGame = new BaseBall();
assertEquals(30, oneGame.compare(123, 123));
assertEquals(10, oneGame.compare(100, 123));
assertEquals(2, oneGame.compare(310, 123));
}
public int compare(int aGuess) {
return compare(aGuess, correctNumber);
}
public int compare(int aGuess, int answer) {
correctNumber = answer;
int compareResult = 0, cCorrect = correctNumber;
//�략
}
~java
public int compare(int aGuess, int answer) {
correctNumber = answer;
int compareResult = 0, cCorrect = correctNumber;
int firstGuess = aGuess / 100 % 10;
int secondGuess = aGuess / 10 % 10;
int thirdGuess = aGuess % 10;
if (cCorrect / 100 == firstGuess)
compareResult++;
cCorrect = cCorrect % 100;
if (cCorrect / 10 == secondGuess)
compareResult++;
cCorrect = cCorrect % 10;
if (cCorrect == thirdGuess)
compareResult++;
compareResult *= 10;
cCorrect = correctNumber;
if ((cCorrect / 100) == secondGuess || (cCorrect / 100) == thirdGuess)
compareResult++;
cCorrect = cCorrect % 100;
if ((cCorrect / 10) == firstGuess || (cCorrect / 10) == thirdGuess)
compareResult++;
cCorrect = cCorrect % 10;
if ((cCorrect == firstGuess) || (cCorrect == secondGuess))
compareResult++;
return compareResult;
}
íŠ¹ì • í�¬ì§€ì…˜ì�˜ 숫ìž�를 얻어오기 위한 반복 부분들 발견, íŠ¹ì • í�¬ì§€ì…˜ì�„ 얻어오는 함수 만들기
~java
int positionNum(int value, int pos) {
if (pos < 1)
throw new IndexOutOfBoundsException("pos값� 1��� 넣어주세요.");
int a = value % (int) Math.pow(10, pos);
return a / (int) Math.pow(10, pos - 1);
}
@Test
public void getPositionNum() {
assertEquals(3, positionNum(123, 1));
assertEquals(2, positionNum(123, 2));
assertEquals(1, positionNum(123, 3));
}
결과 값� �미를 드러낼수 있�� 변경
ë�”ì�´ìƒ� 함수가 this.correctNumberì—� ì�˜ì¡´í• í•„ìš” 없으므로 코드 ê°œì„
~java
public int compare(int aGuess, int cCorrect) {
int firstGuess = positionNum(aGuess,3);
int secondGuess = positionNum(aGuess,2);
int thirdGuess = positionNum(aGuess,1);
int strike=0;
if (positionNum(cCorrect,3) == firstGuess)
strike++;
if (positionNum(cCorrect,2) == secondGuess)
strike++;
if (positionNum(cCorrect,1) == thirdGuess)
strike++;
int ball=0;
if (positionNum(cCorrect,3) == secondGuess || positionNum(cCorrect,3) == thirdGuess)
ball++;
if (positionNum(cCorrect,2) == firstGuess || positionNum(cCorrect,2) == thirdGuess)
ball++;
if ((positionNum(cCorrect,1) == firstGuess) || (positionNum(cCorrect,1) == secondGuess))
ball++;
return ball + strike*10;
}
코드� 약간 패턴� 보�다. inline시키면 보�것 같다. 그래서 xxxGuess 를 inline
~java
public int compare(int aGuess, int answer) {
int cCorrect = answer;
int strike=0;
if (positionNum(cCorrect,3) == positionNum(aGuess,3))
strike++;
if (positionNum(cCorrect,2) == positionNum(aGuess,2))
strike++;
if (positionNum(cCorrect,1) == positionNum(aGuess,1))
strike++;
int ball=0;
if (positionNum(cCorrect,3) == positionNum(aGuess,2) || positionNum(cCorrect,3) == positionNum(aGuess,1))
ball++;
if (positionNum(cCorrect,2) == positionNum(aGuess,3) || positionNum(cCorrect,2) == positionNum(aGuess,1))
ball++;
if ((positionNum(cCorrect,1) == positionNum(aGuess,3)) || (positionNum(cCorrect,1) == positionNum(aGuess,2)))
ball++;
return ball + strike*10;
}
~java
public int compare(int aGuess, int cCorrect) {
final int START_POS = 1,END_POS = 3;
int strike = 0;
for (int pos = END_POS; pos >=START_POS; pos--) {
if (positionNum(cCorrect, pos) == positionNum(aGuess, pos))
strike++;
}
int ball = 0;
for (int corPos = END_POS; corPos >=START_POS; corPos--) {
for (int guePos = END_POS; guePos > 0; guePos--) {
if (corPos != guePos && positionNum(cCorrect, corPos) == positionNum(aGuess,guePos))
ball++;
}
}
return ball + strike * 10;
}
~java
public int compare(int aGuess, int cCorrect) {
final int START_POS = 1, END_POS = 3;
int strike = 0, ball = 0;
for (int corPos = END_POS; corPos >= START_POS; corPos--) {
for (int guePos = END_POS; guePos >= START_POS; guePos--) {
if (positionNum(cCorrect, corPos) == positionNum(aGuess, guePos)) {
if (corPos == guePos)
strike++;
else
ball++;
}
}
}
return ball + strike * 10;
}
~java
public int compare(int aGuess, int cCorrect) {
final int START_POS = 1, END_POS = 3, STRIKE_DELTA = 10, BALL_DELTA = 1;
int result = 0; //10ìž�리가 strike, 1ìž�ë¦¬ê³ ball ê°’
for (int corPos = END_POS; corPos >= START_POS; corPos--)
for (int guePos = END_POS; guePos >= START_POS; guePos--)
if (positionNum(cCorrect, corPos) == positionNum(aGuess, guePos))
result += (corPos == guePos) ? STRIKE_DELTA : BALL_DELTA;
return result;
}
ë�” ê°œì„ í•˜ê³ ì‹¶ìœ¼ë‚˜ 그냥 하기 ì§€ì³�서 여기서 그만..
~java
package test;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
import javax.swing.JOptionPane;
public class BaseBall {
private int correctNumber;
public static void main(String[] args) {
final int END_GAME_NUM = 30;
BaseBall oneGame = new BaseBall();
while (true) {
int result = oneGame.runOneTurn();
if (result == END_GAME_NUM)
break;
else
JOptionPane.showMessageDialog(null,
String.format("%d Strike, %d Ball", result / 10, result % 10));
}
oneGame.displayResult();
}
public int runOneTurn() {
return compare(this.correctNumber, inputGuess());
}
public BaseBall() {
int setNumber = 0;
do {
setNumber = (int) (Math.random() * 10);
} while (setNumber == 0);
correctNumber = setNumber;
do {
setNumber = (int) (Math.random() * 10);
} while (correctNumber == setNumber);
correctNumber = correctNumber * 10 + setNumber;
do {
setNumber = (int) (Math.random() * 10);
} while (correctNumber / 10 == setNumber
|| correctNumber % 10 == setNumber);
correctNumber = correctNumber * 10 + setNumber;
}
public int inputGuess() {
String input = JOptionPane
.showInputDialog("Enter three different number\n");
int guess = Integer.parseInt(input);
return guess;
}
int positionNum(int value, int pos) {
if (pos < 1)
throw new IndexOutOfBoundsException("pos값� 1��");
int a = value % (int) Math.pow(10, pos);
return a / (int) Math.pow(10, pos - 1);
}
public int compare(int aGuess, int cCorrect) {
final int START_POS = 1, END_POS = 3, STRIKE_DELTA = 10, BALL_DELTA = 1;
int result = 0; // 10�리가 strike, 1�리가 ball 값
for (int corPos = END_POS; corPos >= START_POS; corPos--)
for (int guePos = END_POS; guePos >= START_POS; guePos--)
if (positionNum(cCorrect, corPos) == positionNum(aGuess, guePos))
result += (corPos == guePos) ? STRIKE_DELTA : BALL_DELTA;
return result;
}
public void displayResult() {
JOptionPane.showMessageDialog(null, "You are right!\n Answer is "
+ correctNumber);
}
@Test
public void getPositionNum() {
assertEquals(3, positionNum(123, 1));
assertEquals(2, positionNum(123, 2));
assertEquals(1, positionNum(123, 3));
}
@Test
public void test2() {
BaseBall oneGame = new BaseBall();
assertEquals(30, oneGame.compare(123, 123));
assertEquals(10, oneGame.compare(100, 123));
assertEquals(2, oneGame.compare(310, 123));
}
}










