zoukankan      html  css  js  c++  java
  • TensorFlow基于神经网络实现井字棋

    import tensorflow as tf
    import matplotlib.pyplot as plt
    import csv
    import random
    import numpy as np
    
    #井字棋的打印函数
    def print_board(board):
    
        symbols = ['O',' ','X','N']
    
        board_plus1 = [int(x) + 1 for x in board]
    
        print(' ' + symbols[board_plus1[0]] + ' | ' + symbols[board_plus1[1]] + ' | ' + symbols[board_plus1[2]])
    
        print('___________')
    
        print(' ' + symbols[board_plus1[3]] + ' | ' + symbols[board_plus1[4]] + ' | ' + symbols[board_plus1[5]])
    
        print('___________')
    
        print(' ' + symbols[board_plus1[6]] + ' | ' + symbols[board_plus1[7]] + ' | ' + symbols[board_plus1[8]])
    
    
    #变化之后的棋盘 以及最佳落子点 通过旋转棋盘 得到对应的图形记录
    def get_symmetry(board, response, transformation):
         if transformation == 'rotate180':
            new_response = 8 - response
            return(board[::-1], new_response)
         elif transformation == 'rotate90':
              new_response = [6, 3, 0, 7, 4, 1, 8, 5, 2].index(response)
              tuple_board = list(zip(*[board[6:9], board[3:6], board[0:3]]))
              return([value for item in tuple_board for value in item], new_response)
    
         elif transformation == 'rotate270':
              new_response = [2, 5, 8, 1, 4, 7, 0, 3, 6].index(response)
              tuple_board = list(zip(*[board[0:3], board[3:6],board[6:9]]))[::-1]
              return([value for item in tuple_board for value in item], new_response)
         elif transformation == 'flip_v':
               new_response = [6, 7, 8, 3, 4, 5, 0, 1, 2].index(response)
               return(board[6:9] +  board[3:6] + board[0:3], new_response)
         elif transformation == 'flip_h':
           # flip_h = rotate180, then flip_v
               new_response = [2, 1, 0, 5, 4, 3, 8, 7, 6].index(response)
               new_board = board[::-1]
               return(new_board[6:9] +  new_board[3:6] + new_board[0:3],new_response)
         else:
               raise ValueError('Method not implmented.')
    
    #加载文件中的棋盘和最佳落子点数据,并保存成元组
    moves = []
    def get_moves_from_csv(csv_file):
        with open(csv_file, 'rt') as csvfile:
            reader = csv.reader(csvfile, delimiter=',')
            for row in reader:
                moves.append(([int(x) for x in row[0:9]], int(row[9])))
    
        return (moves)
    
    #写入文件 获取一种最优解 得到变形后的其余几种 都存入数据表中
    def wrrite_moves_from_csv(csv_file,data):
        moves=get_moves_from_csv(csv_file)
        with open(csv_file,'a+',newline='') as csvfile:
            writer = csv.writer(csvfile,lineterminator='
    ')
            allmoves=get_other_move(data)
            allmoves=[ x for x in allmoves if (x[0:-1],x[-1]) not in moves]
            writer.writerows(allmoves)
    
    
    def get_other_move(data):
        possible_transforms = ['rotate90', 'rotate180', 'rotate270', 'flip_v', 'flip_h']
        otherMoves=[]
        for transform in possible_transforms:
            (board, response) = get_symmetry(data[0:-1], data[-1], transform)
            new=board+[response]
            new=list(map(lambda x:int(x),new))
            otherMoves.append(new)
    
        return otherMoves
    #返回一个随机变换棋盘和落子点
    def get_rand_move(moves):
        # This function performs random transformations on a board.
        #(board, response) = random.choice(moves)
        possible_transforms = ['rotate90', 'rotate180', 'rotate270', 'flip_v', 'flip_h']
        fourBoards=[]
        #random_transform = random.choice(possible_transforms)
        for board,response in moves:
             for transform in possible_transforms:
                 (board, response) = get_symmetry(board, response, transform)
                 fourBoards.append((board, response))
        return fourBoards
    
    sess = tf.Session()
    moves = get_moves_from_csv('base_tic_tac_toe_moves.csv')
    batch_size = 100
    train_length = 100
    train_set = []
    train_set=moves*train_length
    
    #设置测试集 训练集  测试集最优为6
    test_board = [0, 0, -1, 1, -1, -1, 0, 0, 1]
    train_set = [x for x in train_set if x[0] != test_board]
    
    #创建init_weights()函数和model()函数,分别实现初始化模型变量和模型操作
    def init_weights(shape):
        return(tf.Variable(tf.random_normal(shape)))
    
    
    def model(X, A1, A2, bias1, bias2):
        layer1 = tf.nn.sigmoid(tf.add(tf.matmul(X, A1), bias1))
        layer2 = tf.add(tf.matmul(layer1, A2), bias2)
        return(layer2)
    
    #声明占位符、变量和模型
    X = tf.placeholder(dtype=tf.float32, shape=[None, 9])
    Y = tf.placeholder(dtype=tf.int32, shape=[None])
    A1 = init_weights([9, 81])
    bias1 = init_weights([81])
    A2 = init_weights([81, 9])
    bias2 = init_weights([9])
    
    model_output = model(X, A1, A2, bias1, bias2)
    
    #声明算法模型的损失函数,该函数是最后输出的逻辑变换的平均softmax值 #由之前的概率值转化为对应的预测label的索引
    loss = tf.reduce_mean(tf.nn.sparse_softmax_cross_entropy_with_logits( logits=model_output,labels=Y))
    train_step = tf.train.GradientDescentOptimizer(0.025).minimize(loss)
    prediction = tf.argmax(model_output, 1)
    
    # Initialize variables
    
    init = tf.initialize_all_variables()
    sess.run(init)
    loss_vec = []
    
    for i in range(10000):
           # Select random indices for batch
           rand_indices = np.random.choice(range(len(train_set)), batch_size, replace=False)
           # Get batch
           batch_data = [train_set[i] for i in rand_indices]
           x_input = [x[0] for x in batch_data]
           y_target = np.array([y[1] for y in batch_data])
           # Run training step
           sess.run(train_step, feed_dict={X: x_input, Y: y_target})
           # Get training loss
           temp_loss = sess.run(loss, feed_dict={X: x_input, Y: y_target})
           loss_vec.append(temp_loss)
           if i%1000==0:
               print('iteration ' + str(i) + ' Loss: ' + str(temp_loss))
    
    
    
    test_boards = [test_board]
    feed_dict = {X: test_boards}
    logits = sess.run(model_output, feed_dict=feed_dict)
    
    #print(logits)
    predictions = sess.run(prediction, feed_dict=feed_dict)
    print_board(test_board)
    print(predictions)
    #人机对局监测
    #检测函数 游戏是否结束
    def check(board):
        wins = [[0, 1, 2], [3, 4, 5], [6, 7, 8], [0, 3, 6], [1, 4, 7], [2, 5, 8], [0, 4, 8], [2, 4, 6]]
        for i in range(len(wins)):
            if board[wins[i][0]] == board[wins[i][1]] == board[wins[i][2]] == 1.:
                return (1)
            elif board[wins[i][0]] == board[wins[i][1]] == board[wins[i][2]] == -1.:
                return (1)
        return (0)
    
    #初始化棋盘
    game_tracker = [0, 0, 0, 0, 0, 0, 0, 0, 0]
    win_logical = False
    num_moves = 0
    #实时面板登记
    tempBoard=[]
    while not win_logical:
           player_index = input('Input index of your move (0-8): ')
           # 记录用户操作
           tempBoard.append(game_tracker + [int(player_index)])
           #步数
           num_moves += 1
           # Add player move to game
           try:
             game_tracker[int(player_index)] = 1.
           except:
               print('不合法的输入')
               continue
    
           # Get model's move by first getting all the logits for each index
           [potential_moves] = sess.run(model_output, feed_dict={X:[game_tracker]})
    
           # Now find allowed moves (where game tracker values = 0.0)
           allowed_moves = [ix for ix,x in enumerate(game_tracker) if x==0]
    
           # Find best move by taking argmax of logits if they are in allowed moves
           model_move = np.argmax([x if ix in allowed_moves else -999 for ix,x in enumerate(potential_moves)])
    
           # Add model move to game
           game_tracker[int(model_move)] = -1.
           print('Model has moved')
           print_board(game_tracker)
    
           # Now check for win or too many moves
           if check(game_tracker)==1 or num_moves>=5:
              print('Game Over!')
              if check(game_tracker)==1:
                  wrrite_moves_from_csv('base_tic_tac_toe_moves.csv', tempBoard[-2])
                  wrrite_moves_from_csv('base_tic_tac_toe_moves.csv',tempBoard[-1])
              conKey = input('Input 1 to end this game ')
              if conKey== "1":
                 win_logical = True
              game_tracker = [0, 0, 0, 0, 0, 0, 0, 0, 0]
              tempBoard = []
              num_moves=0

  • 相关阅读:
    JNA 简单示例
    WPF中使用VisiFire制作chart报表
    ActiveMQ CMS 开发环境编译
    c# 程序打包发布
    WPF 程序未处理异常 的捕获
    制作简易浏览器
    C#.NET 支持文件拖放
    C/S代码一例
    Delphi 2010 TStreamReader 和TStreamWriter
    Json数据使用及学习方法
  • 原文地址:https://www.cnblogs.com/x0216u/p/9255014.html
Copyright © 2011-2022 走看看