Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

History

2 Commits

Repository files navigation

binary-search-game-java

importjava.io.IOException;
importjava.util.*;
importjava.util.concurrent.ConcurrentHashMap;
importjava.util.concurrent.CountDownLatch;
importjava.util.concurrent.ThreadLocalRandom;
importjava.util.concurrent.TimeUnit;
/** * Binary Search Game <p> * * @author extremecode716 */publicclassMain {
publicstaticvoidmain(String[] args) {
GameManager.getInstance().addGame("Binary Search Game", newBinarySearchGame(1, 100));
finalCorecore = Core.getInstance();
core.init();
while (!core.isGamesEmpty()) {
core.run();
}
}
}
classCore {
privatefinalGameManagergameManager;
privatefinalExitGameManagerexitGameManager;
privateCore() {
gameManager = GameManager.getInstance();
exitGameManager = ExitGameManager.getInstance();
}
privatestaticclassHolder {
privatestaticfinalCoreINSTANCE = newCore();
}
publicstaticCoregetInstance() {
returnHolder.INSTANCE;
}
publicvoidinit() {
gameManager.init();
}
publicvoidrun() {
update();
rendering();
clearGames();
}
privatevoidupdate() {
gameManager.progress();
}
privatevoidrendering() {
gameManager.rendering();
}
privatevoidclearGames() {
exitGameManager.run();
}
publicbooleanisGamesEmpty() {
returngameManager.isGamesEmpty();
}
}
classGameManager {
privatefinalMap<String, Game> games;
privateGameManager() {
games = newConcurrentHashMap<>();
}
privatestaticclassHolder {
privatestaticfinalGameManagerINSTANCE = newGameManager();
}
publicstaticGameManagergetInstance() {
returnHolder.INSTANCE;
}
publicvoidinit() {
games.forEach((gameName, game) -> game.awake());
games.forEach((gameName, game) -> game.start());
}
publicvoidprogress() {
games.forEach((gameName, game) -> {
if (game.isPlayMode()) {
game.update();
}
});
games.forEach((gameName, game) -> {
if (game.isPlayMode()) {
game.lateUpdate();
}
});
games.forEach((gameName, game) -> game.finalUpdate());
// 물리 처리 (생략)
}
publicvoidrendering() {
games.forEach((gameName, game) -> game.rendering());
}
publicvoidaddGame(StringgameName, Gamegame) {
if (this.games.containsKey(gameName)) {
System.out.printf("=== %s은 이미 실행중입니다. ===%n", gameName);
return;
}
game.setName(gameName);
this.games.put(gameName, game);
}
publicGameremoveGame(StringgameName) {
returnthis.games.remove(gameName);
}
publicbooleanisGamesEmpty() {
returnthis.games.isEmpty();
}
}
abstractclassGame {
publicenumGameState {
NONE,
PLAY,
PAUSE,
STOP,
END
}
protectedStringname;
protectedGameStategameState;
protectedbooleanisExit;
protectedGame() {
this.name = "";
this.gameState = GameState.NONE;
this.isExit = false;
}
publicvoidawake() {
}
publicvoidstart() {
}
publicvoidupdate() {
}
publicvoidlateUpdate() {
}
publicvoidfinalUpdate() {
}
publicvoidrendering() {
}
publicbooleansave() {
returntrue;
}
publicbooleanload() {
returntrue;
}
publicStringgetName() {
returnthis.name;
}
publicvoidsetName(Stringname) {
this.name = name;
}
publicGameStategetGameState() {
returngameState;
}
publicvoidchangeGameState(GameStategameState) {
this.gameState = gameState;
}
publicbooleanisPlayMode() {
returnGameState.PLAY == gameState;
}
publicbooleanisExit() {
returnisExit;
}
publicvoidexit() {
isExit = true;
}
}
classBinarySearchGameextendsGame {
privatestaticfinalintDEFAULT_MIN_N = 1;
privatestaticfinalintDEFAULT_MAX_N = 100;
privatestaticfinallongDEFAULT_TIMEOUT_MS = 5000;
privatestaticfinallongDEFAULT_UPDATE_INTERVAL_MS = 1000;
privatefinalintminN;
privatefinalintmaxN;
publicBinarySearchGame() {
super();
minN = DEFAULT_MIN_N;
maxN = DEFAULT_MAX_N;
}
publicBinarySearchGame(intminN, intmaxN) {
super();
this.minN = minN;
this.maxN = maxN;
}
@Overridepublicvoidawake() {
this.gameState = GameState.PLAY;
isExit = false;
}
@Overridepublicvoidstart() {
finalCountDownLatchlatch = newCountDownLatch(1);
newThread(newGameBreaker(() -> {
System.out.printf("== Enter 키를 누르면 %s이 종료됩니다 ==%n", getName());
latch.countDown();
System.in.read();
ExitGameManager.getInstance().addExitGame(getName());
})).start();
try {
if (!latch.await(DEFAULT_TIMEOUT_MS, TimeUnit.MILLISECONDS)) {
System.out.printf("error CountDownLatch await timeout : %s ms%n", DEFAULT_TIMEOUT_MS);
ExitGameManager.getInstance().addExitGame(getName());
}
} catch (InterruptedExceptione) {
e.printStackTrace();
Thread.currentThread().interrupt();
ExitGameManager.getInstance().addExitGame(getName());
}
}
@Overridepublicvoidupdate() {
try {
finalintn = RandomUtil.RANDOM.nextInt(this.maxN - this.minN + 1) + this.minN;
finalintarraySize = RandomUtil.RANDOM.nextInt(n - this.minN + 1) + 1;
intfindNumber;
intresultIndex;
// 1. 중복되지 않은 무작위 배열 생성int[] uniqueRandomArray = CustomArrays.createUniqueRandomArray(this.minN, n + 1, arraySize);
// 2. 배열 정렬CustomArrays.sort(uniqueRandomArray);
findNumber = uniqueRandomArray[RandomUtil.RANDOM.nextInt(uniqueRandomArray.length)];
// 3. 이진 탐색resultIndex = CustomArrays.binarySearch(uniqueRandomArray, findNumber);
System.out.printf("[%s]%nARRAY => %s%nRESULT => 찾는 숫자 : %d 찾은 위치 : %d%n%n", getName(), Arrays.toString(uniqueRandomArray), findNumber, resultIndex);
TimeUnit.MILLISECONDS.sleep(DEFAULT_UPDATE_INTERVAL_MS);
} catch (Exceptione) {
e.printStackTrace();
Thread.currentThread().interrupt();
ExitGameManager.getInstance().addExitGame(getName());
}
}
}
classExitGameManager {
privatefinalGameManagergameManager;
privatefinalSet<String> exitGames;
privateExitGameManager() {
gameManager = GameManager.getInstance();
exitGames = ConcurrentHashMap.newKeySet();
}
privatestaticclassHolder {
privatestaticfinalExitGameManagerINSTANCE = newExitGameManager();
}
publicstaticExitGameManagergetInstance() {
returnHolder.INSTANCE;
}
publicbooleanaddExitGame(StringgameName) {
returnexitGames.add(gameName);
}
publicbooleanremoveExitGame(StringgameName) {
returnexitGames.remove(gameName);
}
publicvoidrun() {
exitGames.forEach(gameName ->
Optional.ofNullable(gameManager.removeGame(gameName)).ifPresent(game -> {
game.exit();
System.out.printf("%s을 종료합니다.%n", game.getName());
}));
exitGames.clear();
}
}
classRandomUtil {
publicstaticfinalRandomRANDOM;
static {
RANDOM = ThreadLocalRandom.current();
}
privateRandomUtil() {
}
}
@FunctionalInterfaceinterfaceGameBreakerFunc {
voidrun() throwsIOException, InterruptedException;
defaultGameBreakerFuncandThen(GameBreakerFuncafter) {
Objects.requireNonNull(after);
return () -> {
run();
after.run();
};
}
}
classGameBreakerimplementsRunnable {
privatefinalGameBreakerFuncgameBreakerFunc;
publicGameBreaker(GameBreakerFuncfunc) {
gameBreakerFunc = func;
}
@Overridepublicvoidrun() {
try {
gameBreakerFunc.run();
} catch (IOException | RuntimeException | InterruptedExceptione) {
e.printStackTrace();
Thread.currentThread().interrupt();
}
}
}
classCustomArrays {
privateCustomArrays() {
}
publicstaticint[] createUniqueRandomArray(intnumberOrigin, intnumberBound, longsize) {
if (size > numberBound - numberOrigin)
thrownewIllegalArgumentException(String.format("(numberBound[%s] - numberOrigin[%s]):[%s] must be greater than size[%s]",
numberBound, numberOrigin, numberBound - numberOrigin, size));
returnRandomUtil.RANDOM.ints(numberOrigin, numberBound).distinct().limit(size).toArray();
}
publicstaticvoidsort(int[] array) {
Arrays.sort(array);
}
publicstaticintbinarySearch(int[] array, intkey) {
intlow = 0;
inthigh = array.length - 1;
while (low <= high) {
intmid = (low + high) >>> 1;
intmidVal = array[mid];
if (midVal < key)
low = mid + 1;
elseif (midVal > key)
high = mid - 1;
elsereturnmid;
}
return -1;
}
}

About

binary search game java

Topics

Resources

Stars

2 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors