Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tic_tac_toe example #9

Closed
wants to merge 8 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
7 changes: 7 additions & 0 deletions examples/tic_tac_toe/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
run game
---------
go run game_server.go

http://localhost:9090/


171 changes: 171 additions & 0 deletions examples/tic_tac_toe/game_server.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
package main

import (
"io/ioutil"
"log"
"net/http"
"html/template"
"encoding/json"
"github.com/patrikeh/go-deep"
"strings"
"strconv"
)

var templates = template.Must(template.ParseFiles("static/game.html"))
var ttt_NN *deep.Neural

type Board map[string]string

func renderTemplate(w http.ResponseWriter, tmpl string, par map[string]interface{}) {
err := templates.ExecuteTemplate(w, tmpl+".html", par)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
}

func playHandler(w http.ResponseWriter, r *http.Request) {
board, ok := r.URL.Query()["board"]

if !ok || len(board[0]) < 1 {
log.Println("Url Param 'board' is missing")
return
}
var m Board
if len(board[0]) != 17 {
m = Board{
"b1": " ",
"b2": " ",
"b3": " ",
"b4": " ",
"b5": " ",
"b6": " ",
"b7": " ",
"b8": " ",
"b9": " ",
"game over": "false",
}
} else {
m = move(board[0])
}
jData, err := json.Marshal(m)
if err != nil {
panic(err)
}
w.Header().Set("Content-Type", "application/json")
w.Write(jData)
}

func move(board string) Board {
var rez []float64

for _,s := range strings.Split(board, ",") {
if s == "o" {
rez = append(rez, 0.5)
} else if s == "x" {
rez = append(rez, 1.0)
} else if s == " " {
rez = append(rez, 0.0)
}
}

index := 0
v := ttt_NN.Predict(rez)

lrez := -1.0
for indext, j:= range(v) {
if j> lrez {
lrez = j
index = indext
}
}
if rez[index] == 0.0 {
rez[index] = 0.5
}

varmap := Board{
"b1": " ",
"b2": " ",
"b3": " ",
"b4": " ",
"b5": " ",
"b6": " ",
"b7": " ",
"b8": " ",
"b9": " ",
"game over": "false",
}
wb := ""
for i, x := range(rez) {
if x== 0.5 {
varmap["b" + strconv.Itoa(i+1)] = "o"
wb += "o,"
} else if (x==1.0) {
varmap["b" + strconv.Itoa(i+1)] = "x"
wb += "x,"
} else {
wb += " ,"
}
}

if varmap["b1"]+varmap["b2"]+varmap["b3"] == "ooo" {
varmap["game over"] = "true"
}
if varmap["b4"]+varmap["b5"]+varmap["b6"] == "ooo" {
varmap["game over"] = "true"
}
if varmap["b7"]+varmap["b8"]+varmap["b9"] == "ooo" {
varmap["game over"] = "true"
}
if varmap["b1"]+varmap["b4"]+varmap["b7"] == "ooo" {
varmap["game over"] = "true"
}
if varmap["b2"]+varmap["b5"]+varmap["b8"] == "ooo" {
varmap["game over"] = "true"
}
if varmap["b3"]+varmap["b6"]+varmap["b9"] == "ooo" {
varmap["game over"] = "true"
}
if varmap["b1"]+varmap["b5"]+varmap["b9"] == "ooo" {
varmap["game over"] = "true"
}
if varmap["b7"]+varmap["b5"]+varmap["b3"] == "ooo" {
varmap["game over"] = "true"
}
return varmap
}

func rootHandler(w http.ResponseWriter, r *http.Request) {

varmap := map[string]interface{}{
"b1": " ",
"b2": " ",
"b3": " ",
"b4": " ",
"b5": " ",
"b6": " ",
"b7": " ",
"b8": " ",
"b9": " ",
"game over": "false",
}
renderTemplate(w, "game", varmap)
}

func main() {
b, err := ioutil.ReadFile("trained/ttt_complete_for_o.nimi")
if err != nil {
panic(err)
}
ttt_NN, err = deep.Unmarshal(b)

if err != nil {
panic(err)
}
fs := http.FileServer(http.Dir("static/js"))
fs2 := http.FileServer(http.Dir("static/css"))
http.Handle("/js/", http.StripPrefix("/js/", fs))
http.Handle("/css/", http.StripPrefix("/css/", fs2))
http.HandleFunc("/play/", playHandler)
http.HandleFunc("/", rootHandler)
log.Fatal(http.ListenAndServe(":9090", nil))
}
20 changes: 20 additions & 0 deletions examples/tic_tac_toe/static/css/game.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@


table{
border: 1px solid black;
width: 300px;
height:300px
}

tr td {
width: 100px;
height: 100px;
text-align: center;
vertical-align: center;
font-size: 80px !important;
font-weight: bold;
}

.game_over {
display: none;
}
19 changes: 19 additions & 0 deletions examples/tic_tac_toe/static/game.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<html>

<head>
<script type='text/javascript' src='https://code.jquery.com/jquery-1.12.0.min.js'></script>
<script type='text/javascript' src='/js/game.js'></script>
<link rel="stylesheet" type="text/css" href="/css/game.css">

</head>
<h2 class="game_over">Game over!</h2>
<table id="game" class="on" border="1">
<tr><td id="b1">{{.b1}}</td><td id="b2">{{.b2}}</td><td id="b3">{{.b3}}</td><tr>
<tr><td id="b4">{{.b4}}</td><td id="b5">{{.b5}}</td><td id="b6">{{.b6}}</td><tr>
<tr><td id="b7">{{.b7}}</td><td id="b8">{{.b8}}</td><td id="b9">{{.b9}}</td><tr>
</table>

<body>

</body>
</html>
37 changes: 37 additions & 0 deletions examples/tic_tac_toe/static/js/game.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
var player1='x';

$(document).ready(function(){
$('#game td').click(function(){
var clickedBtnID = $(this).attr('id');
var p = $(this).text();
if (p == " ") {
$(this).html(player1);
var tboard = "";
$('#game td').each(function( index ) {
tboard += $( this ).text() + ","
});
tboard = tboard.substring(0, tboard.length - 1);
$.ajax({
type: 'GET',
url: 'play',
data: { board: tboard },
dataType: 'json',
success: function (data) {
$("#b1").html(data["b1"])
$("#b2").html(data["b2"])
$("#b3").html(data["b3"])
$("#b4").html(data["b4"])
$("#b5").html(data["b5"])
$("#b6").html(data["b6"])
$("#b7").html(data["b7"])
$("#b8").html(data["b8"])
$("#b9").html(data["b9"])
if (data["game over"] == "true") {
$('#game td').unbind( "click" );
$('.game_over').removeClass('game_over');
}
}
});
}
});
});
110 changes: 110 additions & 0 deletions examples/tic_tac_toe/trained/tic_tac_toe_training.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
package main

import (
"bufio"
"fmt"
"math/rand"
"os"
"time"
"strings"
"github.com/patrikeh/go-deep"
"github.com/patrikeh/go-deep/training"
"math"
"io/ioutil"
"strconv"
)

func main() {

rand.Seed(time.Now().UnixNano())

data, err := load("./tictac_single.txt")
if err != nil {
panic(err)
}

fmt.Printf("have %d entries\n", len(data))

neural := deep.NewNeural(&deep.Config{
Inputs: 9,
Layout: []int{80, 27, 9},
Activation: deep.ActivationSigmoid,
Mode: deep.ModeBinary,
Weight: deep.NewNormal(1, 0),
})

trainer := training.NewBatchTrainer(training.NewAdam(0.02, 0.9, 0.999, 1e-8), 10, 500, 16)
trainer.Train(neural, data, data, 6000)

dump, err := neural.Marshal()
ioutil.WriteFile("t3.nimi", dump, 0644)
}

func InLimit(a, b, l float64) bool {
return math.Abs(a - b) <= l
}

func load(path string) (training.Examples, error) {
file, err := os.Open(path)
if err != nil {
panic(err)
}
defer file.Close()

var examples training.Examples
scanner := bufio.NewScanner(file)
for scanner.Scan() {
examples = append(examples, toExample(scanner.Text()))
}

if err := scanner.Err(); err != nil {
panic(err)
}
return examples, nil
}

func toExample(in string) training.Example {

var board []float64
var res []float64
var parse []float64
//mt.Println(in)
for _,s := range strings.Split(in, " ") {
v, err := strconv.ParseFloat(s, 64)
if err != nil {
panic(err)
}
intv := (int)(v)
if intv == -1 {
board = append(board, 0.5)
} else if intv == 1 {
board = append(board, 1.0)
} else if intv == 0 {
board = append(board, 0.0)
} else {
board = append(board, 0.0)
}
parse = append(parse, v)

}

y := (int)(parse[len(parse)-1])
board = board[:len(board)-1]

if len(board) != 9 {
fmt.Println(board, res)
panic("wrong")
}

for h:=0 ; h<9 ; h++ {
if y==h {
res = append(res, 1.0)
} else {
res = append(res, 0.0)
}
}
return training.Example{
Response: res,
Input: board,
}
}