Skip to content

Commit

Permalink
dev : 현재 AI가 보는 게임판 상태를 바탕으로 추론한 값 출력
Browse files Browse the repository at this point in the history
그냥 좀 있어 보임
  • Loading branch information
junhoyeo committed May 20, 2018
1 parent d01a7e5 commit af96206
Show file tree
Hide file tree
Showing 3 changed files with 146 additions and 67 deletions.
65 changes: 54 additions & 11 deletions app.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,17 @@
from net import *
from game import *

if __name__ == '__main__':
net = Network(26, [50, 100], 26)
# x = np.array([1.0, 0.5])
# y = network.predict(x)
# print(y)
print('w1 shape : ' + str(net.params['w1'].shape))
print('L b1 shape : ' + str(net.params['b1'].shape))
print('w2 shape : ' + str(net.params['w2'].shape))
print('L b2 shape : ' + str(net.params['b2'].shape))
print('w3 shape : ' + str(net.params['w3'].shape))
print('L b3 shape : ' + str(net.params['b3'].shape))
# if __name__ == '__main__':
# net = Network(26, [50, 100], 26)
# # x = np.array([1.0, 0.5])
# # y = network.predict(x)
# # print(y)
# print('w1 shape : ' + str(net.params['w1'].shape))
# print('L b1 shape : ' + str(net.params['b1'].shape))
# print('w2 shape : ' + str(net.params['w2'].shape))
# print('L b2 shape : ' + str(net.params['b2'].shape))
# print('w3 shape : ' + str(net.params['w3'].shape))
# print('L b3 shape : ' + str(net.params['b3'].shape))

# 현재 게임판의 타일 상태를 입력으로 받음
# 배열의 인덱스 : 흰 타일(0~11 + 조커) + 검은 타일(0~11 + 조커) => 26개 원소(인덱스 0~25)
Expand Down Expand Up @@ -102,6 +102,49 @@
# plt.legend(loc='lower right')
# plt.show()

if __name__ == '__main__':
net = Network(26, [50, 200, 800], 676)
print('w1 shape : ' + str(net.params['w1'].shape))
print('L b1 shape : ' + str(net.params['b1'].shape))
print('w2 shape : ' + str(net.params['w2'].shape))
print('L b2 shape : ' + str(net.params['b2'].shape))
print('w3 shape : ' + str(net.params['w3'].shape))
print('L b3 shape : ' + str(net.params['b3'].shape))
print('w4 shape : ' + str(net.params['w4'].shape))
print('L b4 shape : ' + str(net.params['b4'].shape))
print('network ready\n')

game = newGame()
m1 = ai(1) # monorial 1
m2 = ai(2) # monorial 2

m1.getTiles(game)
m1.sortTiles(game)
m2.getTiles(game)
m2.sortTiles(game)
game.updateAll(m1, m2) # 패 다 뽑았으면 업데이트
print('m1 : tiles\n' + m1.printTiles(game))
print('m2 : tiles\n' + m2.printTiles(game))

# ai에 turn 메소드가 있어서 자신 턴에 드로우 하고 하는 처리를 만들어도 좋을 것 같음
print('m1 : draw')
m1.drawTiles(game)
game.updatePlayerTiles(1, m1) # 드로우 후 업데이트
print('m1 : tiles\n' + m1.printTiles(game))
print('m1 : view\n' + str(m1.getAiView(game)) + '\n') # m1가 보는 게임판 상황 가져오기

# 인공신경망에 input(test)
test_data = []
test_data.append(m1.tile_view)
x = np.array(test_data)
print(x)
y = net.predict(x)
print(y)
print(y.tolist()[0])

# output을 처리 후 행동
# 원래 정답을 구하고 한 100번?쯤 train

# 2. input data, get output

# 3. output과 answer(상대의 타일)를 비교, get loss
Expand Down
128 changes: 82 additions & 46 deletions game.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

import random

def getTileData(tile):
def getTileData(tile, game):
tile_data = []
if tile == 12: # white joker
tile_data.append('white')
Expand All @@ -17,17 +17,38 @@ def getTileData(tile):
else: # white tile
tile_data.append('white')
tile_data.append(tile)
# game.revealed 확인
if tile in game.revealed:
tile_data.append('known')
else:
tile_data.append('unknown')
return tile_data

class newGame:
def __init__(self):
self.deck = []
for tile in range(26):
self.deck.append(tile) # 덱에 타일들을 채움
self.revealed = [] # 공개된 타일을 이곳에 저장한 뒤 하나씩 맞춰보는 식으로 한다
self.player1tiles = [] # player 1 패
self.player2tiles = [] # player 2 패

def updatePlayerTiles(self, playerNum, player):
if playerNum == 1:
self.player1tiles = player.tiles
else:
self.player2tiles = player.tiles
# 사용자 타일 정보를 업데이트

def updateAll(self, player1, player2):
self.updatePlayerTiles(1, player1)
self.updatePlayerTiles(2, player2)

class ai:
def __init__(self):
def __init__(self, _playerNum):
self.playerNum = _playerNum # 해당 ai의 플레이어 번호
self.tiles = [] # 해당 ai가 가진 현재 타일(패)
# self.tiles_side = [] # 같은 인덱스의 현재 타일의 면(앞면 2/뒷면 0)
self.tiles_view = [] # 해당 ai가 보는 게임판 위의 현재 타일 상태(0~25 index로 표현)
# tiles_view는 곧 신경망의 input
self.current_tile = 'none' # 이번 턴 드로우한 타일, 없으면 none
Expand All @@ -38,22 +59,24 @@ def getTiles(self, game):
for tile in newtiles:
game.deck.remove(tile) # 덱에서 빼고
self.tiles.append(tile) # ai 패에 넣기
# for tile in self.tiles:
# self.tiles_side.append(0) # 처음에는 각 모두 뒷면(상대에게 unknown)

def sortTiles(self):
def sortTiles(self, game):
# getTiles() 실행 이후, 랜덤하게 가져온 타일을 정렬
# 13번부터 검은 타일(검은 타일 숫자 = n-13), 12/25번 조커
jokers = []
for tile in self.tiles:
if getTileData(tile)[1] == 'joker':
if getTileData(tile, game)[1] == 'joker':
jokers.append(tile)
self.tiles.remove(tile) # 조커가 있을 경우 정렬 전 조커 인덱스 따로 저장
# 정렬 시작
blackTiles = []
for tile in self.tiles:
if getTileData(tile)[0] == 'black':
if getTileData(tile, game)[0] == 'black':
blackTiles.append(tile) # 먼저 검정 타일은 타일의 인덱스 따로 저장
for idx, tile in enumerate(self.tiles):
if getTileData(tile)[0] == 'black':
if getTileData(tile, game)[0] == 'black':
self.tiles[idx] -= 13 # self.tiles에서는 검정 타일 원래 수만 남겨 놓고(-13)
self.tiles.sort() # 오름차순으로 정렬
for blackTile in blackTiles:
Expand All @@ -71,79 +94,92 @@ def sortTiles(self):
# print('joker : ' + str(joker))
# self.tiles의 랜덤 위치에 처음에 따로 빼 둔 조커를 끼워 넣음

def printTiles(self):
def printTiles(self, game):
tiles = ''
for tile in self.tiles:
tiles += str(getTileData(tile))
tiles += ' '
tiles += str(getTileData(tile, game))
tiles += '\n'
return tiles

def drawTiles(self, game):
if len(game.deck) <= 0:
return # 덱에 카드가 없으면 드로우하지 못함
drawTile = random.choice(game.deck)
game.deck.remove(drawTile)
print(str(getTileData(drawTile))) # print data of drawed tile
self.current_tile = drawTile # 현재 드로우한 타일을 저장(패 깔 때 필요함)
print(str(getTileData(drawTile, game)) + '\n') # print data of drawed tile
# game.deck에서 타일 하나를 랜덤으로 가져와 => random.choice(game.deck)
# self.tiles.append(drawTile) # 현재 타일에 추가
# 이 부분을 그냥 뒷부분에 추가하는 대신, 제대로 된 위치로 가게 수정해야 함
# 어떻게? 리스트의 두 수를 비교한 뒤 색에 따라 추가할지 결정하는 식으로 가능
# 만약 새로 가져온 타일이 조커라면 랜덤으로 넣어야 하니까 먼저 확인해야 함
if (getTileData(drawTile)[1] == 'joker'): # 드로우한 타일이 조커 (랜덤 추가)
self.tiles.insert(random.randrange(len(self.tiles)+1), drawTile)
insert = 0 # 타일을 삽입한 위치
if (getTileData(drawTile, game)[1] == 'joker'): # 드로우한 타일이 조커 (랜덤 추가)
insert = random.randrange(len(self.tiles)+1)
self.tiles.insert(insert, drawTile)
# 현재 패의 랜덤 위치에 조커를 삽입
else:
# getTileData(tile) = [color, number]
# getTileData(tile, game) = [color, number, status]
for i in range(len(self.tiles)):
# self.tiles의 맨 앞에 추가가 가능한지 확인
if getTileData(self.tiles[i])[1] == 'joker':
if getTileData(self.tiles[i], game)[1] == 'joker':
# 현재 탐색 중인 타일이 조커면 패스
continue
if int(getTileData(self.tiles[i])[1]) > int(getTileData(drawTile)[1]):
if int(getTileData(self.tiles[i], game)[1]) > int(getTileData(drawTile, game)[1]):
# 새로 드로우한 타일이 맨 앞 타일의 수보다 크면(앞에 둘 수 있음)
self.tiles.insert(i, drawTile) # 원래 타일 앞에 추가
# print('added on front' + str(getTileData(self.tiles[i])))
insert = i
# print('added on front' + str(getTileData(self.tiles[i], game)))
break
elif int(getTileData(self.tiles[i])[1]) == int(getTileData(drawTile)[1]):
elif int(getTileData(self.tiles[i], game)[1]) == int(getTileData(drawTile, game)[1]):
# 새로 드로우한 타일이 맨 앞 타일의 수와 같으면(색에 따라 앞에 둘 수 있음)
if getTileData(drawTile)[0] == 'white':
if getTileData(drawTile, game)[0] == 'white':
# 두 타일의 색이 다르니까 원래 있던 타일은 검은색
self.tiles.insert(i+1, drawTile)
self.tiles.insert(i + 1, drawTile)
insert = i + 1
# 검은색이 흰색보다 앞에 와야 하므로 원래 타일 다음 자리에 추가
# print('added on next' + str(getTileData(self.tiles[i])))
# print('added on next' + str(getTileData(self.tiles[i], game)))
break
else:
# 새로 드로우한 타일은 검은색, 원래 타일은 흰색:
self.tiles.insert(i, drawTile) # 원래 타일 전 자리에 추가
# print('added on front' + str(getTileData(self.tiles[i])))
insert = i
# print('added on front' + str(getTileData(self.tiles[i], game)))
break
else:
if i == len(self.tiles)-1: # 패에 있는 모든 타일보다도 큰 수의 타일
self.tiles.append(drawTile)
# print('added on last')
continue

if __name__ == '__main__':
game = newGame()
m1 = ai() # monorial 1
m2 = ai() # monorial 2
m1.getTiles(game)
m1.sortTiles()
m2.getTiles(game)
m2.sortTiles()
print('m1 : ' + m1.printTiles())
print('m2 : ' + m2.printTiles())
# game start
while(1):
# m1 turn => ai에 turn() 메소드 만들기
print('m1 : draw')
m1.drawTiles(game)
print('m1 : ' + m1.printTiles())
# todo
# m1가 보는 게임판 상황 가져오기
# 인공신경망에 input(test)
# output을 처리 후 행동
# 원래 정답을 구하고 한 100번?쯤 train
print('m2 : draw')
m2.drawTiles(game)
print('m2 : ' + m2.printTiles())
# self.tiles_side.insert(insert, 0)

def getAiView(self, game):
# 상대방의 타일 = 번호 + 상대 패 인덱스
# 0(상태를 알 수 없음)
# 1(AI가 가진 타일)
# 2 이상(상대방이 가진 타일)
# 모든 타일의 상태가 들어간 사이즈 26(index 0~25)의 배열을 반환하면 됨
view = []
for index in range(26):
# index는 데이터 수집이 필요한 타일의 번호
# index가 본인 패면 1
# index가 game.revealed에 있으면 상대방 타일이므로 2+상대 패 index
# 둘 다 아니면 0
if index in self.tiles: # 본인 패
view.append(1)
elif index in game.revealed: # 본인 것 아니고 공개된 패(상대 패)
# 상대 패는 game.player(?)tiles에 있음
# index가 game.player(?)tiles에 있으면 상대방 타일 2 + 인덱스(tile_idx)
# (?)은 self.playerNum에 따라 결정
tile_idx = 0
if self.playerNum == 1:
tile_idx = game.player2tiles.index(index)
# 상대 playerNum은 2
else:
tile_idx = game.player1tiles.index(index)
# 상대 playerNum은 1
view.append(2 + tile_idx)
else:
view.append(0)
self.tile_view = view
return view
20 changes: 10 additions & 10 deletions net.py
Original file line number Diff line number Diff line change
Expand Up @@ -154,13 +154,13 @@ def gradient(self, x, t):
grads['w4'], grads['b4'] = self.layers['Affine4'].dW, self.layers['Affine4'].db
return grads

if __name__ == '__main__':
net = Network(26, [50, 200, 800], 676)
print('w1 shape : ' + str(net.params['w1'].shape))
print('L b1 shape : ' + str(net.params['b1'].shape))
print('w2 shape : ' + str(net.params['w2'].shape))
print('L b2 shape : ' + str(net.params['b2'].shape))
print('w3 shape : ' + str(net.params['w3'].shape))
print('L b3 shape : ' + str(net.params['b3'].shape))
print('w4 shape : ' + str(net.params['w4'].shape))
print('L b4 shape : ' + str(net.params['b4'].shape))
# if __name__ == '__main__':
# net = Network(26, [50, 200, 800], 676)
# print('w1 shape : ' + str(net.params['w1'].shape))
# print('L b1 shape : ' + str(net.params['b1'].shape))
# print('w2 shape : ' + str(net.params['w2'].shape))
# print('L b2 shape : ' + str(net.params['b2'].shape))
# print('w3 shape : ' + str(net.params['w3'].shape))
# print('L b3 shape : ' + str(net.params['b3'].shape))
# print('w4 shape : ' + str(net.params['w4'].shape))
# print('L b4 shape : ' + str(net.params['b4'].shape))

0 comments on commit af96206

Please sign in to comment.