Commit 293c281c authored by Alexis ANNEIX's avatar Alexis ANNEIX

Initial commit

parents
File added
This source diff could not be displayed because it is too large. You can view the blob instead.
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="FacetManager">
<facet type="Python" name="Python">
<configuration sdkName="Python 2.7.13 virtualenv at ~/.virtualenvs/notification" />
</facet>
</component>
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="Python 2.7.13 virtualenv at ~/.virtualenvs/notification interpreter library" level="application" />
</component>
</module>
\ No newline at end of file
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="Eslint" enabled="true" level="ERROR" enabled_by_default="true" />
<inspection_tool class="HtmlUnknownAttribute" enabled="true" level="WARNING" enabled_by_default="true">
<option name="myValues">
<value>
<list size="0" />
</value>
</option>
<option name="myCustomValuesEnabled" value="false" />
</inspection_tool>
<inspection_tool class="PyCompatibilityInspection" enabled="true" level="WARNING" enabled_by_default="true">
<option name="ourVersions">
<value>
<list size="2">
<item index="0" class="java.lang.String" itemvalue="2.7" />
<item index="1" class="java.lang.String" itemvalue="3.6" />
</list>
</value>
</option>
</inspection_tool>
<inspection_tool class="PyMandatoryEncodingInspection" enabled="true" level="WARNING" enabled_by_default="true">
<option name="myEncodingFormatIndex" value="1" />
</inspection_tool>
<inspection_tool class="PyPackageRequirementsInspection" enabled="false" level="WARNING" enabled_by_default="false">
<option name="ignoredPackages">
<value>
<list size="4">
<item index="0" class="java.lang.String" itemvalue="docopt" />
<item index="1" class="java.lang.String" itemvalue="pybars3" />
<item index="2" class="java.lang.String" itemvalue="pyOpenSSL" />
<item index="3" class="java.lang.String" itemvalue="flask" />
</list>
</value>
</option>
</inspection_tool>
<inspection_tool class="PySetFunctionToLiteralInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="PyUnresolvedReferencesInspection" enabled="true" level="WARNING" enabled_by_default="true">
<option name="ignoredIdentifiers">
<list>
<option value="flask.wrappers.Request.s" />
</list>
</option>
</inspection_tool>
<inspection_tool class="SpellCheckingInspection" enabled="false" level="TYPO" enabled_by_default="false">
<option name="processCode" value="true" />
<option name="processLiterals" value="true" />
<option name="processComments" value="true" />
</inspection_tool>
</profile>
</component>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="MarkdownProjectSettings">
<PreviewSettings splitEditorLayout="SPLIT" splitEditorPreview="PREVIEW" useGrayscaleRendering="false" zoomFactor="1.0" maxImageWidth="0" showGitHubPageIfSynced="false" allowBrowsingInPreview="false" synchronizePreviewPosition="true" highlightPreviewType="NONE" highlightFadeOut="5" highlightOnTyping="true" synchronizeSourcePosition="true" verticallyAlignSourceAndPreviewSyncPosition="true" showSearchHighlightsInPreview="false" showSelectionInPreview="true">
<PanelProvider>
<provider providerId="com.vladsch.idea.multimarkdown.editor.swing.html.panel" providerName="Default - Swing" />
</PanelProvider>
</PreviewSettings>
<ParserSettings gitHubSyntaxChange="false">
<PegdownExtensions>
<option name="ABBREVIATIONS" value="false" />
<option name="ANCHORLINKS" value="true" />
<option name="ASIDE" value="false" />
<option name="ATXHEADERSPACE" value="true" />
<option name="AUTOLINKS" value="true" />
<option name="DEFINITIONS" value="false" />
<option name="DEFINITION_BREAK_DOUBLE_BLANK_LINE" value="false" />
<option name="FENCED_CODE_BLOCKS" value="true" />
<option name="FOOTNOTES" value="false" />
<option name="HARDWRAPS" value="false" />
<option name="HTML_DEEP_PARSER" value="false" />
<option name="INSERTED" value="false" />
<option name="QUOTES" value="false" />
<option name="RELAXEDHRULES" value="true" />
<option name="SMARTS" value="false" />
<option name="STRIKETHROUGH" value="true" />
<option name="SUBSCRIPT" value="false" />
<option name="SUPERSCRIPT" value="false" />
<option name="SUPPRESS_HTML_BLOCKS" value="false" />
<option name="SUPPRESS_INLINE_HTML" value="false" />
<option name="TABLES" value="true" />
<option name="TASKLISTITEMS" value="true" />
<option name="TOC" value="false" />
<option name="WIKILINKS" value="true" />
</PegdownExtensions>
<ParserOptions>
<option name="COMMONMARK_LISTS" value="true" />
<option name="DUMMY" value="false" />
<option name="EMOJI_SHORTCUTS" value="true" />
<option name="FLEXMARK_FRONT_MATTER" value="false" />
<option name="GFM_LOOSE_BLANK_LINE_AFTER_ITEM_PARA" value="false" />
<option name="GFM_TABLE_RENDERING" value="true" />
<option name="GITBOOK_URL_ENCODING" value="false" />
<option name="GITHUB_EMOJI_URL" value="false" />
<option name="GITHUB_LISTS" value="false" />
<option name="GITHUB_WIKI_LINKS" value="true" />
<option name="JEKYLL_FRONT_MATTER" value="false" />
<option name="SIM_TOC_BLANK_LINE_SPACER" value="true" />
</ParserOptions>
</ParserSettings>
<HtmlSettings headerTopEnabled="false" headerBottomEnabled="false" bodyTopEnabled="false" bodyBottomEnabled="false" embedUrlContent="false" addPageHeader="true">
<GeneratorProvider>
<provider providerId="com.vladsch.idea.multimarkdown.editor.swing.html.generator" providerName="Default Swing HTML Generator" />
</GeneratorProvider>
<headerTop />
<headerBottom />
<bodyTop />
<bodyBottom />
</HtmlSettings>
<CssSettings previewScheme="UI_SCHEME" cssUri="" isCssUriEnabled="false" isCssTextEnabled="false" isDynamicPageWidth="true">
<StylesheetProvider>
<provider providerId="com.vladsch.idea.multimarkdown.editor.swing.html.css" providerName="Default Swing Stylesheet" />
</StylesheetProvider>
<ScriptProviders />
<cssText />
</CssSettings>
<HtmlExportSettings updateOnSave="false" parentDir="$ProjectFileDir$" targetDir="$ProjectFileDir$" cssDir="" scriptDir="" plainHtml="false" imageDir="" copyLinkedImages="false" imageUniquifyType="0" targetExt="" useTargetExt="false" noCssNoScripts="false" linkToExportedHtml="true" exportOnSettingsChange="true" regenerateOnProjectOpen="false" />
<LinkMapSettings>
<textMaps />
</LinkMapSettings>
</component>
<component name="MavenImportPreferences">
<option name="generalSettings">
<MavenGeneralSettings>
<option name="mavenHome" value="Bundled (Maven 3)" />
</MavenGeneralSettings>
</option>
</component>
<component name="ProjectDictionaryState">
<dictionary name="alexis" />
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_3" default="false" project-jdk-name="Python 3.6.2 (/usr/local/bin/python3)" project-jdk-type="Python SDK" />
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/Puissance4.iml" filepath="$PROJECT_DIR$/.idea/Puissance4.iml" />
</modules>
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="PhpProjectSharedConfiguration" php_language_level="7" />
</project>
\ No newline at end of file
This diff is collapsed.
In order to use the given code, some requirements are needed :
pip3 install cython
pip3 install pygame
pip3 install kivy
\ No newline at end of file
from player import Player
import random
import math
class AIPlayer(Player):
def __init__(self):
super(AIPlayer, self).__init__()
def calculateHeuristic(self, model, color, depth):
heuristic_ami = 0
heuristic_ennemi = 0
#lignes
for i in range(6):
serie = 0
for j in range(7):
if model[j][i] == color:
serie += 1
else:
if serie >= 4:
return 100000
heuristic_ami += 500 if serie == 3 else 10 if serie == 2 else 0
serie = 0
heuristic_ami += 500 if serie == 3 else 10 if serie == 2 else 0
serie = 0
for j in range(7):
if model[j][i] == -color:
serie += 1
else:
if serie >= 4:
return -100000
heuristic_ennemi += 600 if serie == 3 else 10 if serie == 2 else 0
serie = 0
heuristic_ennemi += 600 if serie == 3 else 10 if serie == 2 else 0
#colonnes
for j in range(7):
serie = 0
for i in range(3):
if model[j][i] == color:
serie += 1
else:
if serie >= 4:
return 100000
heuristic_ami += 500 if serie == 3 else 10 if serie == 2 else 0
serie = 0
heuristic_ami += 500 if serie == 3 else 10 if serie == 2 else 0
serie = 0
for i in range(3):
if model[j][i] == -color:
serie += 1
else:
if serie >= 4:
return -100000
heuristic_ennemi += 600 if serie == 3 else 10 if serie == 2 else 0
serie = 0
heuristic_ennemi += 600 if serie == 3 else 10 if serie == 2 else 0
# #diagonales
for i in range(3):
for j in range(3):
serie = 0
for k in range(4):
if model[j+k][i+k] == color:
serie += 1
else:
if serie >= 4:
return 100000
heuristic_ami += 500 if serie == 3 else 10 if serie == 2 else 0
serie = 0
heuristic_ami += 500 if serie == 3 else 10 if serie == 2 else 0
serie = 0
for k in range(4):
if model[j+k][i+k] == -color:
serie += 1
else:
if serie >= 4:
return -100000
heuristic_ennemi += 600 if serie == 3 else 10 if serie == 2 else 0
serie = 0
heuristic_ennemi += 600 if serie == 3 else 10 if serie == 2 else 0
for i in range(3):
for j in range(3, 7):
serie = 0
for k in range(4):
if model[j-k][i-k] == color:
serie += 1
else:
if serie >= 4:
return 100000
heuristic_ami += 500 if serie == 3 else 10 if serie == 2 else 0
serie = 0
heuristic_ami += 500 if serie == 3 else 10 if serie == 2 else 0
serie = 0
for k in range(4):
if model[j-k][i-k] == -color:
serie += 1
else:
if serie >= 4:
return -100000
heuristic_ennemi += 600 if serie == 3 else 10 if serie == 2 else 0
serie = 0
heuristic_ennemi += 600 if serie == 3 else 10 if serie == 2 else 0
return heuristic_ami - heuristic_ennemi - 100 * depth
def simulate_round(self, model, col, color):
row = 0
while row < len(model[col]) and model[col][row] != 0:
row += 1
if row >= len(model[col]):
return -1
model[col][row] = color
return row
def revert_round(self, model, col, row):
model[col][row] = 0
def minimax_decision(self, model, color, depth=0, max_depth=3):
max_val = -math.inf
best = 0
for col in range(7):
row = self.simulate_round(model, col, color)
if row >= 0:
val = self.min_value(model, -color, depth+1, max_depth)
if val > max_val:
max_val = val
best = col
self.revert_round(model, col, row)
return best
def min_value(self, model, color, depth=0, max_depth=3):
if depth == max_depth or self.__isGameFinished(model):
return self.calculateHeuristic(model, color, depth)
min_val = math.inf
for col in range(7):
row = self.simulate_round(model, col, color)
if row >= 0:
val = self.max_value(model, -color, depth+1, max_depth)
if val < min_val:
min_val = val
self.revert_round(model, col, row)
return min_val
def max_value(self, model, color, depth=0, max_depth=3):
if depth == max_depth or self.__isGameFinished(model):
return self.calculateHeuristic(model, color, depth)
max_val = -math.inf
for col in range(7):
row = self.simulate_round(model, col, color)
if row >= 0:
val = self.min_value(model, -color, depth+1, max_depth)
if val > max_val:
max_val = val
self.revert_round(model, col, row)
return max_val
def __isGameFinished(self, model):
#lignes
for i in range(6):
for j in range(4):
somme = model[j][i] + model[j+1][i] + model[j+2][i] + model[j+3][i]
if somme == 4 or somme == -4:
return True
#colonnes
for j in range(7):
for i in range(3):
somme = model[j][i] + model[j][i+1] + model[j][i+2] + model[j][i+3]
if somme == 4 or somme == -4:
return True
#diagonales
for i in range(3):
for j in range(3):
somme = model[j][i] + model[j+1][i+1] + model[j+2][i+2] + model[j+3][i+3]
if somme == 4 or somme == -4:
return True
for i in range(3):
for j in range(3):
somme = model[j][i] + model[j-1][i+1] + model[j-2][i+2] + model[j-3][i+3]
if somme == 4 or somme == -4:
return True
return False
def getColumn(self, model):
"""Methode qui retourne la colonne à jouer"""
for i in range(7):
if model[i][0] != 0:
return self.minimax_decision(model, self.color, max_depth=4)
return 3
# while True:
# index = random.randint(0, 6)
# if model[index][-1] == 0:
# return index
#on ne devrait pas arriver ici
from player import Player
import random
import math
class AIPlayer(Player):
def __init__(self):
super(AIPlayer, self).__init__()
self.name = 'Alneix'
def calculateHeuristic(self, model, color, depth):
heuristic_ami = 0
heuristic_ennemi = 0
#lignes
for i in range(6):
serie = 0
for j in range(7):
if model[j][i] == color:
serie += 1
else:
if serie >= 4:
return 100000
heuristic_ami += 500 if serie == 3 else 10 if serie == 2 else 0
serie = 0
heuristic_ami += 500 if serie == 3 else 10 if serie == 2 else 0
serie = 0
for j in range(7):
if model[j][i] == -color:
serie += 1
else:
if serie >= 4:
return -100000
heuristic_ennemi += 600 if serie == 3 else 10 if serie == 2 else 0
serie = 0
heuristic_ennemi += 600 if serie == 3 else 10 if serie == 2 else 0
#colonnes
for j in range(7):
serie = 0
for i in range(3):
if model[j][i] == color:
serie += 1
else:
if serie >= 4:
return 100000
heuristic_ami += 500 if serie == 3 else 10 if serie == 2 else 0
serie = 0
heuristic_ami += 500 if serie == 3 else 10 if serie == 2 else 0
serie = 0
for i in range(3):
if model[j][i] == -color:
serie += 1
else:
if serie >= 4:
return -100000
heuristic_ennemi += 600 if serie == 3 else 10 if serie == 2 else 0
serie = 0
heuristic_ennemi += 600 if serie == 3 else 10 if serie == 2 else 0
# #diagonales
for i in range(3):
for j in range(3):
serie = 0
for k in range(4):
if model[j+k][i+k] == color:
serie += 1
else:
if serie >= 4:
return 100000
heuristic_ami += 500 if serie == 3 else 10 if serie == 2 else 0
serie = 0
heuristic_ami += 500 if serie == 3 else 10 if serie == 2 else 0
serie = 0
for k in range(4):
if model[j+k][i+k] == -color:
serie += 1
else:
if serie >= 4:
return -100000
heuristic_ennemi += 600 if serie == 3 else 10 if serie == 2 else 0
serie = 0
heuristic_ennemi += 600 if serie == 3 else 10 if serie == 2 else 0
for i in range(3):
for j in range(3, 7):
serie = 0
for k in range(4):
if model[j-k][i-k] == color:
serie += 1
else:
if serie >= 4:
return 100000
heuristic_ami += 500 if serie == 3 else 10 if serie == 2 else 0
serie = 0
heuristic_ami += 500 if serie == 3 else 10 if serie == 2 else 0
serie = 0
for k in range(4):
if model[j-k][i-k] == -color:
serie += 1
else:
if serie >= 4:
return -100000
heuristic_ennemi += 600 if serie == 3 else 10 if serie == 2 else 0
serie = 0
heuristic_ennemi += 600 if serie == 3 else 10 if serie == 2 else 0
return heuristic_ami - heuristic_ennemi - 100 * depth
def simulate_round(self, model, col, color):
row = 0
while row < len(model[col]) and model[col][row] != 0:
row += 1
if row >= len(model[col]):
return -1
model[col][row] = color
return row
def revert_round(self, model, col, row):
model[col][row] = 0
def minimax_decision(self, model, color, depth=0, max_depth=3):
max_val = -math.inf
best = 0
for col in range(7):
row = self.simulate_round(model, col, color)
if row >= 0:
val = self.min_value(model, -color, depth+1, max_depth)
if val > max_val:
max_val = val
best = col
self.revert_round(model, col, row)
return best
def min_value(self, model, color, depth=0, max_depth=3):
if depth == max_depth or self.__isGameFinished(model):
return self.calculateHeuristic(model, color, depth)
min_val = math.inf
for col in range(7):
row = self.simulate_round(model, col, color)
if row >= 0:
val = self.max_value(model, -color, depth+1, max_depth)
if val < min_val:
min_val = val
self.revert_round(model, col, row)
return min_val
def max_value(self, model, color, depth=0, max_depth=3):
if depth == max_depth or self.__isGameFinished(model):
return self.calculateHeuristic(model, color, depth)
max_val = -math.inf
for col in range(7):
row = self.simulate_round(model, col, color)
if row >= 0:
val = self.min_value(model, -color, depth+1, max_depth)
if val > max_val:
max_val = val
self.revert_round(model, col, row)
return max_val
def __isGameFinished(self, model):
#lignes
for i in range(6):
for j in range(4):
somme = model[j][i] + model[j+1][i] + model[j+2][i] + model[j+3][i]
if somme == 4 or somme == -4:
return True
#colonnes
for j in range(7):
for i in range(3):
somme = model[j][i] + model[j][i+1] + model[j][i+2] + model[j][i+3]
if somme == 4 or somme == -4:
return True
#diagonales
for i in range(3):
for j in range(3):
somme = model[j][i] + model[j+1][i+1] + model[j+2][i+2] + model[j+3][i+3]
if somme == 4 or somme == -4:
return True
for i in range(3):
for j in range(3):
somme = model[j][i] + model[j-1][i+1] + model[j-2][i+2] + model[j-3][i+3]
if somme == 4 or somme == -4:
return True
return False
def getColumn(self, model):
"""Methode qui retourne la colonne à jouer"""
for i in range(7):
if model[i][0] != 0:
return self.minimax_decision(model, self.color, max_depth=4)
return 3
# while True:
# index = random.randint(0, 6)
# if model[index][-1] == 0:
# return index
#on ne devrait pas arriver ici
# -*- coding: utf-8 -*-
import kivy
kivy.require('1.10.0') # ici votre version de kivy
from kivy.app import App
from kivy.config import Config
from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.uix.widget import Widget
from kivy.uix.gridlayout import GridLayout
from kivy.uix.relativelayout import RelativeLayout
from kivy.graphics import Color, Rectangle, Line, Ellipse
from player import HumanPlayer
from aiplayer import AIPlayer
class Grille(GridLayout):
def __init__(self, **kwargs):
super(Grille, self).__init__(**kwargs)
self.cols = 7
self.rows = 6
self.spacing = 2
self.quickaccess = []
for i in range(42):
circ = Puiss4Circle(i)
self.quickaccess.append(circ)
self.add_widget(circ)
class Puiss4Circle(RelativeLayout):
def __init__(self, i, **kwargs):
super(Puiss4Circle, self).__init__(**kwargs)
self.update(0)
def update(self, color):
with self.canvas.before:
if color>0:
Color(0,0,1,1)
elif color<0:
Color(1,0,0,1)
else:
Color(1,1,1,1)
Ellipse(pos=self.to_widget(self.pos[0]+10,self.pos[1]+10), size=[40,40])
class ControlBar(GridLayout):
def __init__(self, **kwargs):
super(ControlBar, self).__init__(**kwargs)
self.cols = 7