-
Notifications
You must be signed in to change notification settings - Fork 0
Commit b2075ff
committed
Imported into Microsoft Visual Studio
diff --git a/.gitignore b/.gitignore
index a48f643..9f32482 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,35 +1,362 @@
-# Prerequisites
-*.d
-
-# Compiled Object files
-*.slo
-*.lo
-*.o
-*.obj
-
-# Precompiled Headers
-*.gch
-*.pch
-
-# Compiled Dynamic libraries
-*.so
-*.dylib
-*.dll
-
-# Fortran module files
-*.mod
-*.smod
-
-# Compiled Static libraries
-*.lai
-*.la
-*.a
-*.lib
-
-# Executables
-*.exe
-*.out
-*.app
-
-# Log files for saved players
-*.log
\ No newline at end of file
+# Prerequisites
+*.d
+
+# Compiled Object files
+*.slo
+*.lo
+*.o
+
+# Precompiled Headers
+*.gch
+
+# Compiled Dynamic libraries
+*.so
+*.dylib
+*.dll
+
+# Fortran module files
+*.mod
+*.smod
+
+# Compiled Static libraries
+*.lai
+*.la
+*.a
+*.lib
+
+# Executables
+*.exe
+*.out
+*.app
+
+
+
+## Ignore Visual Studio temporary files, build results, and
+## files generated by popular Visual Studio add-ons.
+##
+## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
+
+# User-specific files
+*.suo
+*.user
+*.userosscache
+*.sln.docstates
+
+# User-specific files (MonoDevelop/Xamarin Studio)
+*.userprefs
+
+# Build results
+[Dd]ebug/
+[Dd]ebugPublic/
+[Rr]elease/
+[Rr]eleases/
+x64/
+x86/
+bld/
+[Bb]in/
+[Oo]bj/
+[Ll]og/
+
+# Visual Studio 2015/2017 cache/options directory
+.vs/
+# Uncomment if you have tasks that create the project's static files in wwwroot
+#wwwroot/
+
+# Visual Studio 2017 auto generated files
+Generated\ Files/
+
+# MSTest test Results
+[Tt]est[Rr]esult*/
+[Bb]uild[Ll]og.*
+
+# NUNIT
+*.VisualState.xml
+TestResult.xml
+
+# Build Results of an ATL Project
+[Dd]ebugPS/
+[Rr]eleasePS/
+dlldata.c
+
+# Benchmark Results
+BenchmarkDotNet.Artifacts/
+
+# .NET Core
+project.lock.json
+project.fragment.lock.json
+artifacts/
+
+# StyleCop
+StyleCopReport.xml
+
+# Files built by Visual Studio
+*_i.c
+*_p.c
+*_i.h
+*.ilk
+*.meta
+*.obj
+*.iobj
+*.pch
+*.pdb
+*.ipdb
+*.pgc
+*.pgd
+*.rsp
+*.sbr
+*.tlb
+*.tli
+*.tlh
+*.tmp
+*.tmp_proj
+*.log
+*.vspscc
+*.vssscc
+.builds
+*.pidb
+*.svclog
+*.scc
+
+# Chutzpah Test files
+_Chutzpah*
+
+# Visual C++ cache files
+ipch/
+*.aps
+*.ncb
+*.opendb
+*.opensdf
+*.sdf
+*.cachefile
+*.VC.db
+*.VC.VC.opendb
+
+# Visual Studio profiler
+*.psess
+*.vsp
+*.vspx
+*.sap
+
+# Visual Studio Trace Files
+*.e2e
+
+# TFS 2012 Local Workspace
+$tf/
+
+# Guidance Automation Toolkit
+*.gpState
+
+# ReSharper is a .NET coding add-in
+_ReSharper*/
+*.[Rr]e[Ss]harper
+*.DotSettings.user
+
+# JustCode is a .NET coding add-in
+.JustCode
+
+# TeamCity is a build add-in
+_TeamCity*
+
+# DotCover is a Code Coverage Tool
+*.dotCover
+
+# AxoCover is a Code Coverage Tool
+.axoCover/*
+!.axoCover/settings.json
+
+# Visual Studio code coverage results
+*.coverage
+*.coveragexml
+
+# NCrunch
+_NCrunch_*
+.*crunch*.local.xml
+nCrunchTemp_*
+
+# MightyMoose
+*.mm.*
+AutoTest.Net/
+
+# Web workbench (sass)
+.sass-cache/
+
+# Installshield output folder
+[Ee]xpress/
+
+# DocProject is a documentation generator add-in
+DocProject/buildhelp/
+DocProject/Help/*.HxT
+DocProject/Help/*.HxC
+DocProject/Help/*.hhc
+DocProject/Help/*.hhk
+DocProject/Help/*.hhp
+DocProject/Help/Html2
+DocProject/Help/html
+
+# Click-Once directory
+publish/
+
+# Publish Web Output
+*.[Pp]ublish.xml
+*.azurePubxml
+# Note: Comment the next line if you want to checkin your web deploy settings,
+# but database connection strings (with potential passwords) will be unencrypted
+*.pubxml
+*.publishproj
+
+# Microsoft Azure Web App publish settings. Comment the next line if you want to
+# checkin your Azure Web App publish settings, but sensitive information contained
+# in these scripts will be unencrypted
+PublishScripts/
+
+# NuGet Packages
+*.nupkg
+# The packages folder can be ignored because of Package Restore
+**/[Pp]ackages/*
+# except build/, which is used as an MSBuild target.
+!**/[Pp]ackages/build/
+# Uncomment if necessary however generally it will be regenerated when needed
+#!**/[Pp]ackages/repositories.config
+# NuGet v3's project.json files produces more ignorable files
+*.nuget.props
+*.nuget.targets
+
+# Microsoft Azure Build Output
+csx/
+*.build.csdef
+
+# Microsoft Azure Emulator
+ecf/
+rcf/
+
+# Windows Store app package directories and files
+AppPackages/
+BundleArtifacts/
+Package.StoreAssociation.xml
+_pkginfo.txt
+*.appx
+
+# Visual Studio cache files
+# files ending in .cache can be ignored
+*.[Cc]ache
+# but keep track of directories ending in .cache
+!*.[Cc]ache/
+
+# Others
+ClientBin/
+~$*
+*~
+*.dbmdl
+*.dbproj.schemaview
+*.jfm
+*.pfx
+*.publishsettings
+orleans.codegen.cs
+
+# Including strong name files can present a security risk
+# (https://github.com/github/gitignore/pull/2483#issue-259490424)
+#*.snk
+
+# Since there are multiple workflows, uncomment next line to ignore bower_components
+# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
+#bower_components/
+
+# RIA/Silverlight projects
+Generated_Code/
+
+# Backup & report files from converting an old project file
+# to a newer Visual Studio version. Backup files are not needed,
+# because we have git ;-)
+_UpgradeReport_Files/
+Backup*/
+UpgradeLog*.XML
+UpgradeLog*.htm
+ServiceFabricBackup/
+*.rptproj.bak
+
+# SQL Server files
+*.mdf
+*.ldf
+*.ndf
+
+# Business Intelligence projects
+*.rdl.data
+*.bim.layout
+*.bim_*.settings
+*.rptproj.rsuser
+
+# Microsoft Fakes
+FakesAssemblies/
+
+# GhostDoc plugin setting file
+*.GhostDoc.xml
+
+# Node.js Tools for Visual Studio
+.ntvs_analysis.dat
+node_modules/
+
+# Visual Studio 6 build log
+*.plg
+
+# Visual Studio 6 workspace options file
+*.opt
+
+# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
+*.vbw
+
+# Visual Studio LightSwitch build output
+**/*.HTMLClient/GeneratedArtifacts
+**/*.DesktopClient/GeneratedArtifacts
+**/*.DesktopClient/ModelManifest.xml
+**/*.Server/GeneratedArtifacts
+**/*.Server/ModelManifest.xml
+_Pvt_Extensions
+
+# Paket dependency manager
+.paket/paket.exe
+paket-files/
+
+# FAKE - F# Make
+.fake/
+
+# JetBrains Rider
+.idea/
+*.sln.iml
+
+# CodeRush
+.cr/
+
+# Python Tools for Visual Studio (PTVS)
+__pycache__/
+*.pyc
+
+# Cake - Uncomment if you are using it
+# tools/**
+# !tools/packages.config
+
+# Tabs Studio
+*.tss
+
+# Telerik's JustMock configuration file
+*.jmconfig
+
+# BizTalk build output
+*.btp.cs
+*.btm.cs
+*.odx.cs
+*.xsd.cs
+
+# OpenCover UI analysis results
+OpenCover/
+
+# Azure Stream Analytics local run output
+ASALocalRun/
+
+# MSBuild Binary and Structured Log
+*.binlog
+
+# NVidia Nsight GPU debugger configuration file
+*.nvuser
+
+# MFractors (Xamarin productivity tool) working folder
+.mfractor/
\ No newline at end of file
diff --git a/Genetic.cpp b/Genetic.cpp
index 4ebd56a..3d04407 100644
--- a/Genetic.cpp
+++ b/Genetic.cpp
@@ -1,6 +1,7 @@
#include "Genetic.h"
+
//mutationRate is in the range [0, 1], greedyPercent is in the range [0, 1]
Genetic::Genetic(const float mutationRate, const float greedyPercent)
: m_mutationRate(clamp(mutationRate, 0.0f, 1.0f))
@@ -15,7 +16,7 @@ void Genetic::setPopulationSize(int populationSize){
//Make new players based on how successful the current ones are
void Genetic::breed(vector<playerContainer<NeuralPlayer> >& population){
vector<playerContainer<NeuralPlayer> > newPop;
- newPop.resize(m_populationSize);
+ newPop.reserve(m_populationSize);
//Keep the best greedyPercent of last generation
int numToKeep = (int)(m_greedyPercent * (float)m_populationSize);
@@ -25,18 +26,18 @@ void Genetic::breed(vector<playerContainer<NeuralPlayer> >& population){
//Copy the players which are being kept from greedyPercent
for(int i = 0; i < numToKeep; ++i){
- newPop[i] = population[m_populationSize - 1 - i];
+ newPop.push_back(population[m_populationSize - 1 - i]);
}
//Iterates over the remaining child elements
for(int i = numToKeep; i < m_populationSize; ++i){
playerContainer<NeuralPlayer> parent1 = pickParent(population);
playerContainer<NeuralPlayer> parent2 = pickParent(population);
- vector<Matrix> newWeights = crossOver(parent1, parent2);
+ vector<MatrixXd> newWeights = crossOver(parent1, parent2);
playerContainer<NeuralPlayer> temp(population[m_populationSize-1 - i]);
temp.player.neural.setWeights(newWeights);
- newPop[i] = temp;
+ newPop.push_back(temp);
}
population = newPop;
}
@@ -50,17 +51,17 @@ void Genetic::mutate(vector<playerContainer<NeuralPlayer> >& population){
int numToKeep = (int)(m_greedyPercent * (float)m_populationSize);
for(int i = numToKeep; i < m_populationSize; ++i){
- vector<Matrix> weights = population[i].player.neural.getWeights();
+ vector<MatrixXd> weights = population[i].player.neural.getWeights();
size_t layers = weights.size();
//For each layer
for(size_t lay = 0; lay < layers; ++lay){
- int rows = weights[lay].numRows();
- int cols = weights[lay].numCols();
+ int rows = weights[lay].rows();
+ int cols = weights[lay].cols();
//Randomly mutate each element
- for(int row = 0; row < rows; ++row){
- for(int col = 0; col < cols; ++col){
+ for(int col = 0; col < cols; ++col){
+ for(int row = 0; row < rows; ++row){
//Mutate with a certain chance
if( ((float)rand() / float(RAND_MAX)) < m_mutationRate){
weights[lay](row, col) += distribution(gen);
@@ -98,10 +99,10 @@ playerContainer<NeuralPlayer> Genetic::pickParent(
return population.back();
}
-vector<Matrix> Genetic::crossOver(const playerContainer<NeuralPlayer> parent1,
- const playerContainer<NeuralPlayer> parent2){
- vector<Matrix> weights1;
- vector<Matrix> weights2;
+vector<MatrixXd> Genetic::crossOver(const playerContainer<NeuralPlayer>& parent1,
+ const playerContainer<NeuralPlayer>& parent2){
+ vector<MatrixXd> weights1;
+ vector<MatrixXd> weights2;
//Parent 1
weights1 = parent1.player.neural.getWeights();
@@ -111,12 +112,12 @@ vector<Matrix> Genetic::crossOver(const playerContainer<NeuralPlayer> parent1,
//For each layer
for(size_t i = 0; i < length; ++i){
- int rows = weights1[i].numRows();
- int cols = weights1[i].numCols();
+ int rows = weights1[i].rows();
+ int cols = weights1[i].cols();
//Cross breed matrix
- for(int row = 0; row < rows; ++row){
- for(int col = 0; col < cols; ++col){
+ for(int col = 0; col < cols; ++col){
+ for(int row = 0; row < rows; ++row){
//50% chance of being from parent1 or parent2
if(rand() % 2 == 0){
weights1[i](row, col) = weights2[i](row, col);
diff --git a/Genetic.h b/Genetic.h
index 3c1563a..9d3ed76 100644
--- a/Genetic.h
+++ b/Genetic.h
@@ -4,7 +4,9 @@
#include <iostream>
#include <random>
-#include "Matrix.h"
+#include <Eigen/Dense>
+using namespace Eigen;
+
#include "NeuralNet.h"
#include "Player.h"
#include "main.h"
@@ -24,8 +26,8 @@ public:
void mutate(vector<playerContainer<NeuralPlayer> >& population);
private:
- vector<Matrix> crossOver(const playerContainer<NeuralPlayer> parent1,
- const playerContainer<NeuralPlayer> parent2);
+ vector<MatrixXd> crossOver(const playerContainer<NeuralPlayer>& parent1,
+ const playerContainer<NeuralPlayer>& parent2);
playerContainer<NeuralPlayer> pickParent(
const vector<playerContainer<NeuralPlayer> >& population) const;
diff --git a/Matrix.cpp b/Matrix.cpp
deleted file mode 100644
index e445b7d..0000000
--- a/Matrix.cpp
+++ /dev/null
@@ -1,244 +0,0 @@
-
-#include "Matrix.h"
-
-
-
-
-//Size Constructor
-Matrix::Matrix(const unsigned int rows, const unsigned int cols)
- : m_rows(rows)
- , m_cols(cols){
- if (rows == 0 || cols == 0){
- cerr << "Error: Matrix size constructor has 0 size" << endl;
- exit(1);
- }
- m_data = new double[rows * cols];
-}
-
-//Copy constructor
-Matrix::Matrix(const Matrix& m)
- : m_rows(m.m_rows)
- , m_cols(m.m_cols){
- if (m_rows <= 0 || m_cols <= 0){
- cerr << "Error: Matrix copy constructor has 0 size" << endl;
- exit(1);
- }
- m_data = new double[m_rows * m_cols];
- for(unsigned int row = 0; row < m_rows; ++row){
- for(unsigned int col = 0; col < m_cols; ++col){
- m_data[m_cols * row + col] = m.m_data[m.m_cols * row + col];
- }
- }
-}
-
-//Sets all matrix elements to 'n'
-void Matrix::initialize(const int n){
- for(unsigned int row = 0; row < m_rows; ++row){
- for(unsigned int col = 0; col < m_cols; ++col){
- m_data[m_cols * row + col] = n;
- }
- }
-}
-
-vector<double> Matrix::toVector() const{
- vector<double> temp;
- for(unsigned int row = 0; row < m_rows; ++row){
- for(unsigned int col = 0; col < m_cols; ++col){
- temp.push_back(m_data[m_cols * row + col]);
- }
- }
- return temp;
-}
-
-unsigned int Matrix::numRows() const{
- return m_rows;
-}
-
-unsigned int Matrix::numCols() const{
- return m_cols;
-}
-
-//Prints the matrix as a grid to the console
-void Matrix::printData() const{
- for(unsigned int row = 0; row < m_rows; ++row){
- for(unsigned int col = 0; col < m_cols; ++col){
- printf("%9.4lf", m_data[m_cols * row + col]);
- }
- cout << endl;
- }
-}
-
-//Returns a copy of itself which is transposed
-Matrix Matrix::transpose() const{
- Matrix temp(m_cols, m_rows);
- for(unsigned int row = 0; row < m_rows; ++row){
- for(unsigned int col = 0; col < m_cols; ++col){
- temp(col, row) = m_data[m_cols * row + col];
- }
- }
- return temp;
-}
-
-//Destructor
-Matrix::~Matrix(){
- delete[] m_data;
-}
-
-//Override = operator to copy each element
-void Matrix::operator= (const Matrix& m){
- if(m.numRows() != m_rows || m.numCols() != m_cols){
- cerr << "Error: Matrix sizes are not equivalent. Cannot perform \
- assignment." << endl;
- exit(1);
- }
- for(unsigned int row = 0; row < m_rows; ++row){
- for(unsigned int col = 0; col < m_cols; ++col){
- m_data[m_cols * row + col] = m.m_data[m.m_cols * row + col];
- }
- }
-}
-
-//Override - (unary) operator to negate each element
-Matrix Matrix::operator- () const{
- Matrix temp(m_rows, m_cols);
- for(unsigned int row = 0; row < m_rows; ++row){
- for(unsigned int col = 0; col < m_cols; ++col){
- temp(row, col) = -1 * m_data[m_cols * row + col];
- }
- }
- return temp;
-}
-
-//Override + operator to add elementwise
-Matrix Matrix::operator+ (const Matrix& a) const{
- if(a.numRows() != m_rows || a.numCols() != m_cols){
- cerr << "Error: Matrix sizes are not equivalent. Cannot perform \
- addition." << endl;
- exit(1);
- }
- Matrix temp(m_rows, m_cols);
- for(unsigned int row = 0; row < m_rows; ++row){
- for(unsigned int col = 0; col < m_cols; ++col){
- temp(row, col) = a(row, col) + m_data[m_cols * row + col];
- }
- }
- return temp;
-}
-
-//Override - operator to subtract elementwise
-Matrix Matrix::operator- (const Matrix& a) const{
- if(a.numRows() != m_rows || a.numCols() != m_cols){
- cerr << "Error: Matrix sizes are not equivalent. Cannot perform \
- subtraction." << endl;
- exit(1);
- }
- Matrix temp(m_rows, m_cols);
- for(unsigned int row = 0; row < m_rows; ++row){
- for(unsigned int col = 0; col < m_cols; ++col){
- temp(row, col) = m_data[m_cols * row + col] - a(row, col);
- }
- }
- return temp;
-}
-
-//Override * operator to multiply elementwise by a constant
-Matrix Matrix::operator* (const int a) const{
- Matrix temp(m_rows, m_cols);
- for(unsigned int row = 0; row < m_rows; ++row){
- for(unsigned int col = 0; col < m_cols; ++col){
- temp(row, col) = a * m_data[m_cols * row + col];
- }
- }
- return temp;
-}
-
-//Override * operator to perform standard matrix multiplication
-Matrix Matrix::operator* (const Matrix& a) const{
- if(m_cols != a.numRows()){
- cerr << "Error: Matrix sizes are incompatible. Cannot perform \
- matrix multiplication." << endl;
- exit(1);
- }
- Matrix temp(m_rows, a.m_cols);
- for(unsigned int row = 0; row < m_rows; ++row){
- for(unsigned int col = 0; col < a.m_cols; ++col){
- //perform cross product between current row and current column
- temp(row, col) = 0;
- for(unsigned int element = 0; element < m_cols; ++element){
- temp(row, col) += m_data[m_cols * row + element]
- * a(element, col);
- }
- }
- }
- return temp;
-}
-
-//Override () operator to allow access at a specific location
-double& Matrix::operator() (const unsigned int row, const unsigned int col){
- if (row >= m_rows || col >= m_cols ){
- cerr << "Error: Matrix subscript out of bounds (too large)." << endl;
- exit(1);
- }
- return m_data[m_cols * row + col];
-}
-
-//Override () operator to allow access at a specific location
-double Matrix::operator() (const unsigned int row,
- const unsigned int col) const{
- if (row >= m_rows || col >= m_cols){
- cerr << "Error: Matrix subscript out of bounds (too large)." << endl;
- exit(1);
- }
- return m_data[m_cols * row + col];
-}
-
-//Sets each element to a random double in the range [min, max] with specified
-//resolution
-void Matrix::initRand(const double min, const double max,
- const unsigned int resolution){
- if(min > max){
- cerr << "Error: initRand(): Min is larger than max." << endl;
- exit(1);
- }
- if(resolution == 0){
- cerr << "Error: initRand(): Resolution is equal to 0" << endl;
- exit(1);
- }
- for(unsigned int row = 0; row < m_rows; ++row){
- for(unsigned int col = 0; col < m_cols; ++col){
- /* resolution represents how many pieces each (int) is broken into.
- * bound is used because we can generate ints better than doubles.
- * bound is the product of the total range * resolution.
- * Afterward, we divide bound by resolution to get a double.
- */
- int bound = (int)( (double)resolution * (max - min) );
- //The double value is created by dividing bound by resolution
- double randDouble = min + (double)(rand() % bound) / resolution;
- //Passed into the matrix
- m_data[m_cols * row + col] = randDouble;
- }
- }
-}
-
-Matrix Matrix::addRowsCols(unsigned int extraRows, unsigned int extraCols,
- const double value){
- unsigned int newRows = m_rows + extraRows;
- unsigned int newCols = m_cols + extraCols;
- Matrix temp(newRows, newCols);
-
- for(unsigned int row = 0; row < newRows; ++row){
- for(unsigned int col = 0; col < newCols; ++col){
- if(row < m_rows && col < m_cols){
- temp(row, col) = m_data[m_cols * row + col];
- } else{
- temp(row, col) = value;
- }
- }
- }
- return temp;
-}
-
-
-
-
-
diff --git a/Matrix.h b/Matrix.h
deleted file mode 100644
index 3e04666..0000000
--- a/Matrix.h
+++ /dev/null
@@ -1,52 +0,0 @@
-#ifndef MATRIX_H
-#define MATRIX_H
-
-#include <stdexcept>
-#include <vector>
-#include <iostream>
-#include <time.h>
-#include <stdlib.h>
-#include <stdio.h>
-
-using std::cout;
-using std::cin;
-using std::cerr;
-using std::endl;
-using std::vector;
-
-class Matrix {
-public:
- Matrix(const unsigned int rows, const unsigned int cols);
- Matrix(const Matrix& m);
- ~Matrix();
-
- double& operator() (const unsigned int row, const unsigned int col);
- double operator() (const unsigned int row, const unsigned int col) const;
- void operator= (const Matrix& m);
-
- std::vector<double> toVector() const;
-
- unsigned int numRows() const;
- unsigned int numCols() const;
- void printData() const;
-
- Matrix operator- () const;
- Matrix operator+ (const Matrix& a) const;
- Matrix operator- (const Matrix& a) const;
- Matrix operator* (const int a) const;
- Matrix operator* (const Matrix& a) const;
-
- Matrix transpose() const;
- void initialize(const int n);
- void initRand(const double min, const double max,
- const unsigned int resolution=20);
-
- Matrix addRowsCols(unsigned int extraRows, unsigned int extraCols,
- const double value);
-
-private:
- unsigned int m_rows, m_cols;
- double* m_data;
-};
-
-#endif
diff --git a/NeuralNet.cpp b/NeuralNet.cpp
index d86037e..e0865af 100644
--- a/NeuralNet.cpp
+++ b/NeuralNet.cpp
@@ -9,11 +9,12 @@ NeuralNet::NeuralNet(){
//Constructor takes in the structure of the network as a matrix
NeuralNet::NeuralNet(const vector<unsigned int>& layerSizes)
: m_layerSizes(layerSizes){
+ unsigned int numLayers = layerSizes.size() - 1;
+ m_weights.reserve(numLayers);
+
//Create vectors for weights. Each entry is a matrix for that layer
- for(unsigned int i = 0; i < layerSizes.size() - 1; ++i){
- Matrix tempWeight(layerSizes[i] + 1, layerSizes[i+1]);
- tempWeight.initRand(-1, 1);
- m_weights.push_back(tempWeight);
+ for(unsigned int i = 0; i < numLayers; ++i){
+ m_weights.push_back(MatrixXd::Random(layerSizes[i] + 1, layerSizes[i+1]));
}
}
@@ -32,7 +33,7 @@ void NeuralNet::printWeights() const{
cout << "Current weights:" << endl;
for(unsigned int i = 0; i < m_weights.size(); ++i){
cout << "================================================" << endl;
- m_weights[i].printData();
+ cout << m_weights[i] << endl;
}
cout << "================================================" << endl;
}
@@ -54,13 +55,12 @@ bool NeuralNet::saveToFile(string fileName) const{
outputFile << "\n";
for(unsigned int lay = 0; lay < m_weights.size(); ++lay){
- unsigned int numRows = m_weights[lay].numRows();
- unsigned int numCols = m_weights[lay].numCols();
+ unsigned int rows = m_weights[lay].rows();
+ unsigned int cols = m_weights[lay].cols();
- for(unsigned int i = 0; i < numRows; ++i){
- for(unsigned int j = 0; j < numCols; ++j){
- Matrix cur = m_weights[lay];
- outputFile << cur(i, j) << " ";
+ for(unsigned int col = 0; col < cols; ++col){
+ for(unsigned int row = 0; row < rows; ++row){
+ outputFile << m_weights[lay](row, col) << " ";
}
}
}
@@ -88,12 +88,14 @@ bool NeuralNet::loadFromFile(string fileName){
}
for(unsigned int lay = 0; lay < numLayers - 1; ++lay){
- Matrix cur(m_layerSizes[lay] + 1, m_layerSizes[lay + 1]);
- for(unsigned int i = 0; i < cur.numRows(); ++i){
- for(unsigned int j = 0; j < cur.numCols(); ++j){
+ unsigned int rows = m_layerSizes[lay] + 1;
+ unsigned int cols = m_layerSizes[lay + 1];
+ MatrixXd cur(rows, cols);
+ for(unsigned int col = 0; col < cols; ++col){
+ for(unsigned int row = 0; row < rows; ++row){
double temp;
inputFile >> temp;
- cur(i, j) = temp;
+ cur(row, col) = temp;
}
}
m_weights.push_back(cur);
@@ -112,27 +114,31 @@ bool NeuralNet::loadFromFile(string fileName){
}
//Performs forward propagation using m_weights and 'input'
-Matrix NeuralNet::forward(const Matrix& input) const{
+RowVectorXd NeuralNet::forward(const RowVectorXd& input) const{
+ unsigned int numLayers = m_weights.size();
+
//Stores the previous layer's output
- vector<Matrix> layers;
+ vector<RowVectorXd> layers;
+ layers.reserve(numLayers + 1);
layers.push_back(input);
- for(unsigned int lay = 0; lay < m_weights.size(); ++lay){
- //Add extra col with 1.0 in it for bias
- Matrix prev = (layers.back()).addRowsCols(0, 1, 1.0f);
+ for(unsigned int lay = 0; lay < numLayers; ++lay){
+ unsigned int numCols = layers[lay].size();
+ RowVectorXd prev(numCols + 1);
+ prev << layers[lay], 1.0;
//Cur = f(layers * weights + bias)...where f(x) is nonlinearity funtion
- layers.push_back( applyNonlinearity(prev * m_weights[lay], sigmoid) );
+ layers.push_back(applyNonlinearity(prev * m_weights[lay], Activations::relu));
}
- return layers.back();
+ return layers[numLayers];
}
-vector<Matrix> NeuralNet::getWeights() const{
+vector<MatrixXd> NeuralNet::getWeights() const{
return m_weights;
}
//Sets the internal weights
-void NeuralNet::setWeights(const vector<Matrix>& weights){
+void NeuralNet::setWeights(const vector<MatrixXd>& weights){
if (weights.size() == 0 || weights.size() != m_weights.size()){
cerr << "Error: setWeights(): Weights have different sizes." << endl;
exit(1);
@@ -142,20 +148,14 @@ void NeuralNet::setWeights(const vector<Matrix>& weights){
}
}
-//Applies the nonlinearity function (sigmoid) elementwise
-Matrix NeuralNet::applyNonlinearity(const Matrix& input,
- double(*callback)(double)) const{
- Matrix temp(input);
- for(unsigned int row = 0; row < input.numRows(); ++row){
- for(unsigned int col = 0; col < input.numCols(); ++col){
- //Applies the callback to each element of input
- temp(row, col) = callback(input(row, col));
- }
- }
- return temp;
+RowVectorXd NeuralNet::applyNonlinearity(const RowVectorXd& input, Activations activation) const{
+ switch (activation){
+ case Activations::sigmoid: // 1 / (1 + e^-x)
+ return (((-1 * input.array()).exp() + 1).inverse()).matrix();
+ case Activations::relu: // max(0, x)
+ return ((input.array() > 0).cast<double>() * input.array()).matrix();
+ default:
+ return input;
+ }
}
-//Sigmoid function. Returns a double between (0, 1)
-double NeuralNet::sigmoid(const double x){
- return 1 / (1 + exp(-x));
-}
diff --git a/NeuralNet.h b/NeuralNet.h
index ff3f64a..362af2d 100644
--- a/NeuralNet.h
+++ b/NeuralNet.h
@@ -1,7 +1,9 @@
#ifndef NN_H
#define NN_H
-#include "Matrix.h"
+#include <Eigen/Dense>
+using namespace Eigen;
+
#include <iostream>
#include <fstream>
#include <vector>
@@ -10,36 +12,43 @@
using std::cout;
using std::cin;
+using std::cerr;
using std::endl;
using std::vector;
using std::ofstream;
using std::ifstream;
using std::string;
+enum Activations { sigmoid, relu };
+
class NeuralNet {
+
+
public:
NeuralNet();
NeuralNet(const vector<unsigned int>& layerSizes);
NeuralNet(const NeuralNet& nn);
- Matrix forward(const Matrix& input) const;
+ RowVectorXd forward(const RowVectorXd& input) const;
void printWeights() const;
void operator= (const NeuralNet& nn);
- vector<Matrix> getWeights() const;
- void setWeights(const vector<Matrix>& weights);
+ vector<MatrixXd> getWeights() const;
+ void setWeights(const vector<MatrixXd>& weights);
bool saveToFile(string fileName) const;
bool loadFromFile(string fileName);
private:
vector<unsigned int> m_layerSizes;
- vector<Matrix> m_weights;
+ vector<MatrixXd> m_weights;
- Matrix applyNonlinearity(const Matrix& input,
- double(*funct)(double)) const;
- static double sigmoid(const double x);
+ /*RowVectorXd applyNonlinearity(const RowVectorXd& input,
+ double(*funct)(double)) const;*/
+ RowVectorXd applyNonlinearity(const RowVectorXd& input, Activations activation) const;
+ //static double sigmoid(const double x);
+ //static double relu(const double x);
};
#endif
diff --git a/Player.cpp b/Player.cpp
index df231b7..27dfbad 100644
--- a/Player.cpp
+++ b/Player.cpp
@@ -24,8 +24,7 @@ void Player::operator= (const Player& right){
}
/*
vector<double> Player::getMove() const{
- Matrix temp(1, 9);
- temp.initRand(-1, 1);
+ MatrixXd temp = MatrixXd::Random(1, 9);
return temp.toVector();
}*/
@@ -68,8 +67,8 @@ void NeuralPlayer::operator= (const NeuralPlayer& right){
neural = right.neural;
}
-vector<double> NeuralPlayer::getMove(const Matrix& input) const{
- return neural.forward(input).toVector();
+RowVectorXd NeuralPlayer::getMove(const RowVectorXd& input) const{
+ return neural.forward(input);
}
//----------ManualPlayer--------------
@@ -98,7 +97,7 @@ void ManualPlayer::operator= (const ManualPlayer& right){
Player::operator=(right);
}
-vector<double> ManualPlayer::getMove(const Matrix& input) const{
+RowVectorXd ManualPlayer::getMove(const RowVectorXd& input) const{
unsigned int row, col;
char eater;
m_os << "Your move, of the form \"row, col\": ";
@@ -106,10 +105,10 @@ vector<double> ManualPlayer::getMove(const Matrix& input) const{
row --;
col --;
- Matrix temp(m_rows, m_cols);
- temp.initialize(0);
- temp(row, col) = 1;
- return temp.toVector();
+ RowVectorXd temp(m_rows * m_cols);
+ temp << RowVectorXd::Constant(m_rows * m_cols, 0);
+ temp(row * m_cols + col) = 1.0;
+ return temp;
}
//----------PerfectPlayer--------------
diff --git a/Player.h b/Player.h
index f15f861..6449e6e 100644
--- a/Player.h
+++ b/Player.h
@@ -1,8 +1,10 @@
#ifndef PLAYER_H
#define PLAYER_H
+#include <Eigen/Dense>
+using namespace Eigen;
+
#include <vector>
-#include "Matrix.h"
#include "NeuralNet.h"
using std::cout;
@@ -22,7 +24,7 @@ public:
void operator= (const Player& right);
bool operator< (const Player& right) const;
- virtual vector<double> getMove(const Matrix& input) const = 0;
+ virtual RowVectorXd getMove(const RowVectorXd& input) const = 0;
void addToFitness(const double a);
double getFitness() const;
@@ -44,7 +46,7 @@ public:
void operator= (const NeuralPlayer& right);
- virtual vector<double> getMove(const Matrix& input) const override;
+ virtual RowVectorXd getMove(const RowVectorXd& input) const override;
NeuralNet neural;
private:
@@ -61,7 +63,7 @@ public:
void operator= (const ManualPlayer& right);
- virtual vector<double> getMove(const Matrix& input) const override;
+ virtual RowVectorXd getMove(const RowVectorXd& input) const override;
private:
istream& m_is;
@@ -79,7 +81,7 @@ public:
void operator= (const PerfectPlayer& right);
- virtual vector<double> getMove(const Matrix& input) const override;
+ virtual vector<double> getMove(const VectorXd& input) const override;
private:
double winningMove() const;
diff --git a/Population.h b/Population.h
index 0d7953c..2f006df 100644
--- a/Population.h
+++ b/Population.h
@@ -7,13 +7,16 @@
#include <vector>
#include <algorithm>
#include <string>
+#include <ctime>
+
+#include <Eigen/Dense>
+using namespace Eigen;
-#include "Matrix.h"
#include "NeuralNet.h"
#include "Player.h"
#include "TicTacToe.h"
#include "Genetic.h"
-#include "UltimateTTT.h"
+//#include "UltimateTTT.h"
using std::cout;
using std::cin;
@@ -29,7 +32,7 @@ public:
Population<Game>();
void init(unsigned int seed = 1, istream& is = cin, ostream& os = cout);
- void train(bool verbose);
+ time_t train(bool verbose);
string saveBest(string path);
void loadBest(string path, string name = "");
@@ -140,7 +143,8 @@ string Population<Game>::saveBest(string path){
template <template <class, class> class Game>
-void Population<Game>::train(bool verbose){
+time_t Population<Game>::train(bool verbose){
+ time_t startTime = time(NULL);
for(int generation = 0; generation < m_iterations; ++generation){
//Play games with every permutaiton of players
roundRobin();
@@ -149,7 +153,7 @@ void Population<Game>::train(bool verbose){
sort(m_population.begin(), m_population.end(),
comparePlayerContainer<NeuralPlayer>);
- m_hallOfFame.push_back(m_population.back());
+ m_hallOfFame.push_back(m_population[m_populationSize - 1]);
//Print board
if(verbose){
@@ -179,6 +183,7 @@ void Population<Game>::train(bool verbose){
m_population[i].player.resetFitness();
}
}
+ return time(NULL) - startTime;
}
@@ -241,6 +246,7 @@ void Population<Game>::init(unsigned int seed, istream& is, ostream& os){
}
m_ga.setPopulationSize(m_populationSize);
+ m_hallOfFame.reserve(m_iterations);
}
template <template <class, class> class Game>
diff --git a/README.md b/README.md
index 1fbf255..f4e88d8 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-# TicTacToeMachineLearning
-The goal of this project is to train the computer to play tic tac toe at a superhuman level. This is a rather trivial problem, but I'm simply using it as a chance to learn more about machine learning. My approach is overkill, but this is just a fun project.
-
-I'm using a neural network trained by a genetic algorithm to learn tic tac toe. I start with a random population of players. Each generation they play every other player once. Fitness points are awarded for their record: 0 points for each loss, 0.5 for each tie, and 1 point for each win. I then evolve the the players based on normal genetic algorithm techniques (mutation, breeding, crossover, etc.). The goal is to maximize the player's fitness.
+# TicTacToeMachineLearning
+The goal of this project is to train the computer to play tic tac toe at a superhuman level. This is a rather trivial problem, but I'm simply using it as a chance to learn more about machine learning. My approach is overkill, but this is just a fun project.
+
+I'm using a neural network trained by a genetic algorithm to learn tic tac toe. I start with a random population of players. Each generation they play every other player once. Fitness points are awarded for their record: 0 points for each loss, 0.5 for each tie, and 1 point for each win. I then evolve the the players based on normal genetic algorithm techniques (mutation, breeding, crossover, etc.). The goal is to maximize the player's fitness.
diff --git a/TicTacToe.h b/TicTacToe.h
index f7d97eb..530bb82 100644
--- a/TicTacToe.h
+++ b/TicTacToe.h
@@ -1,7 +1,9 @@
#ifndef TTT_H
#define TTT_H
-#include "Matrix.h"
+#include <Eigen/Dense>
+using namespace Eigen;
+
#include "NeuralNet.h"
#include "Player.h"
@@ -12,6 +14,7 @@
using std::cout;
using std::cin;
+using std::cerr;
using std::endl;
using std::vector;
using std::pair;
@@ -35,13 +38,13 @@ private:
bool isEmpty() const;
bool isFull() const;
- Matrix toMatrix() const;
- Matrix toPlayerPerspective(const States state) const;
+ RowVectorXd toMatrix() const;
+ RowVectorXd toPlayerPerspective(const States state) const;
States getBoardAtPosition(const int position) const;
void setBoardAtPosition(const int position, const States state);
- vector<unsigned int> bestMoves(const vector<double>& input) const;
+ RowVectorXi bestMoves(const RowVectorXd& input) const;
void printBoard() const;
bool hasWon() const;
@@ -104,28 +107,24 @@ bool TicTacToe<T1, T2>::isFull() const{
//Returns a vector of the preferred moves starting with most preferred
template <class T1, class T2>
-vector<unsigned int> TicTacToe<T1, T2>::bestMoves(
- const vector<double>& input) const{
- vector<unsigned int> temp;
+RowVectorXi TicTacToe<T1, T2>::bestMoves(const RowVectorXd& input) const{
+ Matrix<int, 1, 9> ret;
vector< pair<double, unsigned int> > inputPair;
-
- temp.resize(NUM_OUTPUTS, -1);
+ inputPair.reserve(9);
//Populate inputPair
for(unsigned int i = 0; i < NUM_OUTPUTS; ++i){
- inputPair.push_back(make_pair(input[i], i));
+ inputPair.push_back(make_pair(input(i), i));
}
sort(inputPair.begin(), inputPair.end());
- //Populate temp
+ //Populate ret
for(unsigned int i = 0; i < NUM_OUTPUTS; ++i){
- temp[i] = inputPair[i].second;
+ ret(8 - i) = inputPair[i].second;
}
- //Reverse temp
- reverse(temp.begin(), temp.end());
- return temp;
+ return ret;
}
//Prints the current board to the console
@@ -154,13 +153,11 @@ void TicTacToe<T1, T2>::printBoard() const{
* representation so it can be passed into other methods.
*/
template <class T1, class T2>
-Matrix TicTacToe<T1, T2>::toMatrix() const{
- Matrix temp(1, NUM_OUTPUTS);
+RowVectorXd TicTacToe<T1, T2>::toMatrix() const{
+ RowVectorXd temp(NUM_OUTPUTS);
- for(int i = 0; i < 3; ++i){
- for(int j = 0; j < 3; ++j){
- temp(0, 3 * i + j) = (float)getBoardAtPosition(3 * i + j);
- }
+ for(int i = 0; i < 9; ++i){
+ temp(i) = (double)getBoardAtPosition(i);
}
return temp;
}
@@ -172,19 +169,17 @@ Matrix TicTacToe<T1, T2>::toMatrix() const{
- empty squares = 0
*/
template <class T1, class T2>
-Matrix TicTacToe<T1, T2>::toPlayerPerspective(const States state) const{
- Matrix temp(toMatrix());
+RowVectorXd TicTacToe<T1, T2>::toPlayerPerspective(const States state) const{
+ RowVectorXd temp = toMatrix();
- for(unsigned int i = 0; i < temp.numRows(); ++i){
- for(unsigned int j = 0; j < temp.numCols(); ++j){
- States cur = static_cast<States>(temp(i, j));
- if(cur == States::empty){
- temp(i, j) = 0.0;
- } else if(cur == state){
- temp(i, j) = 1.0;
- } else{
- temp(i, j) = -1.0;
- }
+ for(unsigned int i = 0; i < 9; ++i){
+ States cur = static_cast<States>((int)temp(i));
+ if(cur == States::empty){
+ temp(i) = 0.0;
+ } else if(cur == state){
+ temp(i) = 1.0;
+ } else{
+ temp(i) = -1.0;
}
}
return temp;
@@ -258,7 +253,7 @@ bool TicTacToe<T1, T2>::hasWon() const{
template <class T1, class T2>
bool TicTacToe<T1, T2>::takeTurn(const States state, const int turn){
//holds the list of desired moves in order of preference
- vector<unsigned int> moves;
+ RowVectorXi moves;
//Diagnostics
if(m_verbose){
@@ -266,7 +261,7 @@ bool TicTacToe<T1, T2>::takeTurn(const States state, const int turn){
}
//player 1 controls 'X' squares, player 2 controls 'O' squares
- Matrix playerPerspective = toPlayerPerspective(state);
+ RowVectorXd playerPerspective = toPlayerPerspective(state);
if(state == States::playerX){
moves = bestMoves(m_player1.player.getMove(playerPerspective));
} else{
@@ -275,8 +270,8 @@ bool TicTacToe<T1, T2>::takeTurn(const States state, const int turn){
//Make the best move from available squares
for(int i = 0; i < NUM_OUTPUTS; ++i){
- if(getBoardAtPosition(moves[i]) == States::empty){
- setBoardAtPosition(moves[i], state);
+ if(getBoardAtPosition(moves(i)) == States::empty){
+ setBoardAtPosition(moves(i), state);
break;
}
}
diff --git a/TicTacToeMachineLearning.sln b/TicTacToeMachineLearning.sln
new file mode 100644
index 0000000..61f2553
--- /dev/null
+++ b/TicTacToeMachineLearning.sln
@@ -0,0 +1,31 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 15
+VisualStudioVersion = 15.0.27703.2035
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TicTacToeMachineLearning", "TicTacToeMachineLearning.vcxproj", "{AE943583-6E21-47EC-BFC2-F37CA248C5A9}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|x64 = Debug|x64
+ Debug|x86 = Debug|x86
+ Release|x64 = Release|x64
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {AE943583-6E21-47EC-BFC2-F37CA248C5A9}.Debug|x64.ActiveCfg = Debug|x64
+ {AE943583-6E21-47EC-BFC2-F37CA248C5A9}.Debug|x64.Build.0 = Debug|x64
+ {AE943583-6E21-47EC-BFC2-F37CA248C5A9}.Debug|x86.ActiveCfg = Debug|Win32
+ {AE943583-6E21-47EC-BFC2-F37CA248C5A9}.Debug|x86.Build.0 = Debug|Win32
+ {AE943583-6E21-47EC-BFC2-F37CA248C5A9}.Release|x64.ActiveCfg = Release|x64
+ {AE943583-6E21-47EC-BFC2-F37CA248C5A9}.Release|x64.Build.0 = Release|x64
+ {AE943583-6E21-47EC-BFC2-F37CA248C5A9}.Release|x86.ActiveCfg = Release|Win32
+ {AE943583-6E21-47EC-BFC2-F37CA248C5A9}.Release|x86.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {7CBB95EE-B334-49D0-B4E3-EB36EAE13774}
+ EndGlobalSection
+EndGlobal
diff --git a/TicTacToeMachineLearning.vcxproj b/TicTacToeMachineLearning.vcxproj
new file mode 100644
index 0000000..5e818ca
--- /dev/null
+++ b/TicTacToeMachineLearning.vcxproj
@@ -0,0 +1,123 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <VCProjectVersion>15.0</VCProjectVersion>
+ <ProjectGuid>{AE943583-6E21-47EC-BFC2-F37CA248C5A9}</ProjectGuid>
+ <Keyword>Win32Proj</Keyword>
+ <WindowsTargetPlatformVersion>10.0.17134.0</WindowsTargetPlatformVersion>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v141</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>v141</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v141</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>v141</PlatformToolset>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="Shared">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <LinkIncremental>true</LinkIncremental>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <LinkIncremental>true</LinkIncremental>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>D:/MinGW/include/eigen-eigen-5a0156e40feb/;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <Optimization>Disabled</Optimization>
+ </ClCompile>
+ <Link>
+ <TargetMachine>MachineX86</TargetMachine>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Console</SubSystem>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>D:/MinGW/include/eigen-eigen-5a0156e40feb/;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <TargetMachine>MachineX86</TargetMachine>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Console</SubSystem>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="Genetic.cpp" />
+ <ClCompile Include="main.cpp" />
+ <ClCompile Include="Matrix.cpp" />
+ <ClCompile Include="NeuralNet.cpp" />
+ <ClCompile Include="Player.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="Genetic.h" />
+ <ClInclude Include="main.h" />
+ <ClInclude Include="Matrix.h" />
+ <ClInclude Include="NeuralNet.h" />
+ <ClInclude Include="Player.h" />
+ <ClInclude Include="Population.h" />
+ <ClInclude Include="TicTacToe.h" />
+ <ClInclude Include="UltimateTTT.h" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project>
\ No newline at end of file
diff --git a/TicTacToeMachineLearning.vcxproj.filters b/TicTacToeMachineLearning.vcxproj.filters
new file mode 100644
index 0000000..4feca21
--- /dev/null
+++ b/TicTacToeMachineLearning.vcxproj.filters
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+ <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+ </Filter>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+ <Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
+ </Filter>
+ <Filter Include="Resource Files">
+ <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
+ <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav</Extensions>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="Genetic.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="main.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="Matrix.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="NeuralNet.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="Player.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="Genetic.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="main.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="Matrix.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="NeuralNet.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="Player.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="Population.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="TicTacToe.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="UltimateTTT.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ </ItemGroup>
+</Project>
\ No newline at end of file
diff --git a/Todo.txt b/Todo.txt
index 3ec2b32..b39e9ec 100644
--- a/Todo.txt
+++ b/Todo.txt
@@ -1,7 +1,8 @@
TODO List
- Code formatting
-- Improve Matrix class functionality/cleanliness
+- XXXXXXXXXXXXX Improve Matrix class functionality/cleanliness XXXXXXXXXXXXX
+- Use Eigen matrix library
- Ultimate Tic Tac Toe
- Random Player (chooses moves randomly)
- Timekeeping (execution time)
diff --git a/Training Times.xlsx b/Training Times.xlsx
new file mode 100644
index 0000000..fe8cf0b
Binary files /dev/null and b/Training Times.xlsx differ
diff --git a/UltimateTTT.h b/UltimateTTT.h
index 5f47f14..45cb8fa 100644
--- a/UltimateTTT.h
+++ b/UltimateTTT.h
@@ -133,10 +133,11 @@ bool UltimateTTT<T1, T2>::subBoardTied(const int subBoard) const{
template <class T1, class T2>
vector<unsigned int> UltimateTTT<T1, T2>::bestMoves(
const vector<double>& input) const{
- vector<unsigned int> temp;
- temp.resize(NUM_OUTPUTS, -1);
-
- vector< pair<double, unsigned int> > inputPair;
+
+ vector<unsigned int> ret;
+ vector< pair<double, unsigned int> > inputPair;
+ ret.reserve(NUM_OUTPUTS);
+ inputPair.reserve(NUM_OUTPUTS);
//Populate inputPair
for(unsigned int i = 0; i < NUM_OUTPUTS; ++i){
@@ -147,12 +148,12 @@ vector<unsigned int> UltimateTTT<T1, T2>::bestMoves(
//Populate temp
for(unsigned int i = 0; i < NUM_OUTPUTS; ++i){
- temp[i] = inputPair[i].second;
+ ret.push_back(inputPair[i].second);
}
//Reverse temp
- reverse(temp.begin(), temp.end());
- return temp;
+ reverse(ret.begin(), ret.end());
+ return ret;
}
//Prints the current board to the console
diff --git a/main.cpp b/main.cpp
index 81926da..4b1da79 100644
--- a/main.cpp
+++ b/main.cpp
@@ -2,16 +2,17 @@
#include "main.h"
#include "Population.h"
+#include <Eigen/Dense>
int main(){
- srand(time(NULL));
-
+ srand((unsigned int)time(NULL));
+
//Where your player log files are stored
string path = "data/";
Population<TicTacToe> pop;
-
+ /*
ManualPlayer tempHuman1(cin, cout, 10, 9);
playerContainer<ManualPlayer> human1(tempHuman1);
@@ -26,7 +27,7 @@ int main(){
UltimateTTT<NeuralPlayer, NeuralPlayer> ttt(machine1, machine2, true);
ttt.playGame();
-
+ */
char loadPlayer;
cout << "Do you want to load a trained player? (y/n): ";
@@ -36,8 +37,10 @@ int main(){
if(loadPlayer == 'y' || loadPlayer == 'Y'){
pop.loadBest(path);
} else{
- pop.init(time(NULL));
- pop.train(false);
+ pop.init((unsigned int)time(NULL));
+ time_t trainingTime = pop.train(false);
+
+ cout << "Time to train: " << trainingTime << endl;
char savePlayer;
cout << "Do you want to save the best player to a file? (y/n): ";
diff --git a/makefile b/makefile
index 8167680..9100c15 100644
--- a/makefile
+++ b/makefile
@@ -5,21 +5,22 @@ Warnings = -Wall -Wextra -Wdouble-promotion -Wswitch-default -Wfloat-equal \
Sanitize = -fsanitize=address -fsanitize=undefined
TestingFlags = -Og -g
ReleaseFlags = -O3
-Targets = main.cpp Matrix.cpp NeuralNet.cpp Player.cpp Genetic.cpp
+Targets = main.cpp NeuralNet.cpp Player.cpp Genetic.cpp
+Include = -isystem d:/MinGW/include/eigen-eigen-5a0156e40feb/
all: $(Targets)
$(RM) a
- g++ $(CompilerFlags) $(Warnings) $(TestingFlags) $(Targets)
+ g++ $(CompilerFlags) $(Warnings) $(TestingFlags) $(Targets) $(Include)
run: $(Targets)
$(RM) a
- g++ $(CompilerFlags) $(Warnings) $(TestingFlags) $(Targets)
+ g++ $(CompilerFlags) $(Warnings) $(TestingFlags) $(Targets) $(Include)
./a.exe
fast: $(Targets)
$(RM) a
- g++ $(CompilerFlags) $(Warnings) $(ReleaseFlags) $(Targets)
+ g++ $(CompilerFlags) $(Warnings) $(ReleaseFlags) $(Targets) $(Include)
clean:
$(RM) a1 parent 685e59a commit b2075ffCopy full SHA for b2075ff
File tree
Expand file treeCollapse file tree
20 files changed
+741
-476
lines changedFilter options
Expand file treeCollapse file tree
20 files changed
+741
-476
lines changed.gitignore
Copy file name to clipboard+362-35Lines changed: 362 additions & 35 deletions
Original file line number | Diff line number | Diff line change | |
---|---|---|---|
| |||
1 |
| - | |
2 |
| - | |
3 |
| - | |
4 |
| - | |
5 |
| - | |
6 |
| - | |
7 |
| - | |
8 |
| - | |
9 |
| - | |
10 |
| - | |
11 |
| - | |
12 |
| - | |
13 |
| - | |
14 |
| - | |
15 |
| - | |
16 |
| - | |
17 |
| - | |
18 |
| - | |
19 |
| - | |
20 |
| - | |
21 |
| - | |
22 |
| - | |
23 |
| - | |
24 |
| - | |
25 |
| - | |
26 |
| - | |
27 |
| - | |
28 |
| - | |
29 |
| - | |
30 |
| - | |
31 |
| - | |
32 |
| - | |
33 |
| - | |
34 |
| - | |
35 |
| - | |
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
| 202 | + | |
| 203 | + | |
| 204 | + | |
| 205 | + | |
| 206 | + | |
| 207 | + | |
| 208 | + | |
| 209 | + | |
| 210 | + | |
| 211 | + | |
| 212 | + | |
| 213 | + | |
| 214 | + | |
| 215 | + | |
| 216 | + | |
| 217 | + | |
| 218 | + | |
| 219 | + | |
| 220 | + | |
| 221 | + | |
| 222 | + | |
| 223 | + | |
| 224 | + | |
| 225 | + | |
| 226 | + | |
| 227 | + | |
| 228 | + | |
| 229 | + | |
| 230 | + | |
| 231 | + | |
| 232 | + | |
| 233 | + | |
| 234 | + | |
| 235 | + | |
| 236 | + | |
| 237 | + | |
| 238 | + | |
| 239 | + | |
| 240 | + | |
| 241 | + | |
| 242 | + | |
| 243 | + | |
| 244 | + | |
| 245 | + | |
| 246 | + | |
| 247 | + | |
| 248 | + | |
| 249 | + | |
| 250 | + | |
| 251 | + | |
| 252 | + | |
| 253 | + | |
| 254 | + | |
| 255 | + | |
| 256 | + | |
| 257 | + | |
| 258 | + | |
| 259 | + | |
| 260 | + | |
| 261 | + | |
| 262 | + | |
| 263 | + | |
| 264 | + | |
| 265 | + | |
| 266 | + | |
| 267 | + | |
| 268 | + | |
| 269 | + | |
| 270 | + | |
| 271 | + | |
| 272 | + | |
| 273 | + | |
| 274 | + | |
| 275 | + | |
| 276 | + | |
| 277 | + | |
| 278 | + | |
| 279 | + | |
| 280 | + | |
| 281 | + | |
| 282 | + | |
| 283 | + | |
| 284 | + | |
| 285 | + | |
| 286 | + | |
| 287 | + | |
| 288 | + | |
| 289 | + | |
| 290 | + | |
| 291 | + | |
| 292 | + | |
| 293 | + | |
| 294 | + | |
| 295 | + | |
| 296 | + | |
| 297 | + | |
| 298 | + | |
| 299 | + | |
| 300 | + | |
| 301 | + | |
| 302 | + | |
| 303 | + | |
| 304 | + | |
| 305 | + | |
| 306 | + | |
| 307 | + | |
| 308 | + | |
| 309 | + | |
| 310 | + | |
| 311 | + | |
| 312 | + | |
| 313 | + | |
| 314 | + | |
| 315 | + | |
| 316 | + | |
| 317 | + | |
| 318 | + | |
| 319 | + | |
| 320 | + | |
| 321 | + | |
| 322 | + | |
| 323 | + | |
| 324 | + | |
| 325 | + | |
| 326 | + | |
| 327 | + | |
| 328 | + | |
| 329 | + | |
| 330 | + | |
| 331 | + | |
| 332 | + | |
| 333 | + | |
| 334 | + | |
| 335 | + | |
| 336 | + | |
| 337 | + | |
| 338 | + | |
| 339 | + | |
| 340 | + | |
| 341 | + | |
| 342 | + | |
| 343 | + | |
| 344 | + | |
| 345 | + | |
| 346 | + | |
| 347 | + | |
| 348 | + | |
| 349 | + | |
| 350 | + | |
| 351 | + | |
| 352 | + | |
| 353 | + | |
| 354 | + | |
| 355 | + | |
| 356 | + | |
| 357 | + | |
| 358 | + | |
| 359 | + | |
| 360 | + | |
| 361 | + | |
| 362 | + |
0 commit comments