Hmm. Einer der Punkte, die die Aktionen von Moderatoren auf Habré regeln, lautet wie folgt: Sie sollten keine Artikel überspringen, die sich nur schwach oder gar nicht auf IT-bezogene Themen beziehen. Was den Autor sofort zum Nachdenken brachte, ob sein Beitrag, der einige Phasen der Programmierung seines lustigen und aufregenden Haustierprojekts beschreibt, eine einfache KI, die ein neuronales Netzwerk auf der Grundlage des FANN-Rubin-Wrappers zum Spielen von Kreuzen aufbaut, in direktem Zusammenhang steht zu den "IT-Thema" Nullen? Die Frage enthält keine versteckte Koketterie, da die Beschreibung der Logik des Programmcodes in meiner Geschichte bei weitem nicht von größter Bedeutung ist. "Ja, das ist eine böse Ironie!" - du sagst. - Weiß nicht.
OK. Diese Entwicklung de facto ist ein Beispiel für eine Reihe seltsamer Beobachtungen des Autors, für eine Reihe von Bekannten und sogar für Freunde und Freunde, von denen er in den letzten Jahren ... an die Literaturstunden seiner Zeit erinnert wurde, als er noch sehr, sehr alt war sekundäre sowjetische Schule. Trotz seiner ständigen Überzeugung, dass es immer möglich ist, nur an etwas vorbei zu gehen, werden bestimmte Charaktere russischer Klassiker im Laufe der Zeit immer häufiger in Erinnerung gerufen. Oder sollte es vielleicht so sein?
Also sofort ... nach dem ersten Start beginnt das Programm mit dem Selbstlernprozess und spielt mehrere Zehntausende (eine Minute - maximal zwei) von Tausenden von Spielen mit sich selbst (die Anzahl steht natürlich zur Bearbeitung zur Verfügung in der Konfiguration (angesichts des unten beschriebenen nicht ganz üblichen Algorithmus, der der Logik dieser KI zugrunde liegt - Experimente dieser Art können auch interessantes Material für Schlussfolgerungen liefern). Es simuliert den Lernprozess, der vielen anderen künstlichen Intelligenz innewohnt, mit dem einzigen Unterschied, dass beide "Spieler" gleichermaßen nicht wissen, wie man spielt, und absolut zufällige Züge machen. Es gelten jedoch die Spielregeln: Wenn der zufällige Zug nicht übereinstimmt, muss das Programm fortgesetzt werden, und dementsprechend wechselt die Gewinnerseite zur Gewinnerseite. Alles ist fair: keine Löschungen und Hacks, keine versteckten Vorlieben,Keine gefälschten Dopingtests für Sie, die die Ergebnisse von Sportspielen im wirklichen Leben oft auf den Kopf stellen.
: csv- , AI, () , - , , .
, ? , : , . , , (, - "") : "" , ... , , .
- , ( ), - . - ... , - , , .
. : , . , , , , , , , : (/). -, Tic Tac Toe - , - ? - , . , , , , - , , ?... , "" ; , " " , - " ", , " !".
, Artificial Intelligence. , 3x3, -, ? , , , , , , , - , ? AI, " " ; - , .
, " ". () , , - . ? , :
if row[6].to_i - row[3].to_i == 1
x_data.push([row[0].to_i])
y_data.push([1]) # , .. , .
end
? - . , .. . ?
, Tic Tac Toe AI with Neural Network ( ). , – : , – – . , , , .
, , - , , . , , , ... ?
. “"... , ? – , , : “ , , ”. , “ ” ; , “ ”. , , ; , . , , , , , , , , : , “ , ”.
. , , , . , , - , ... , - , , , .
- ( - life style). , :
WINNING_TRIADS = [
[0, 1, 2],
[3, 4, 5],
[6, 7, 8],
[0, 3, 6],
[1, 4, 7],
[2, 5, 8],
[6, 4, 2],
[0, 4, 8]
].freeze
, csv- , :
def fork?
WINNING_TRIADS.select do |x|
@board[x[0]] == @board[x[1]] && @board[x[2]].class != @board[x[0]].class &&
place_x?(x[0]) ||
@board[x[1]] == @board[x[2]] && @board[x[0]].class != @board[x[2]].class &&
place_x?(x[1]) ||
@board[x[0]] == @board[x[2]] && @board[x[1]].class != @board[x[2]].class &&
place_x?(x[0])
end
end
, ...
if @game.fork?.size > 1
... .
, . : , , , . , .
:
DANGEROUS_SITUATIONS_1 = [
[6, 4, 2],
[0, 4, 8]
].freeze
DANGEROUS_SITUATIONS_2 = [
[0, 4, 7],
[0, 4, 5],
[2, 4, 3],
[2, 4, 7],
[3, 4, 8],
[1, 4, 8],
[1, 4, 6],
[5, 4, 6]
].freeze
def fork_danger_1?
DANGEROUS_SITUATIONS_1.detect do |x|
@board[x[0]] == @board[x[2]] &&
@board[x[0]] != @board[x[1]]
end
end
def fork_danger_2?
DANGEROUS_SITUATIONS_2.detect do |x|
@board[x[0]] == @board[x[2]] &&
@board[x[0]] != @board[x[1]]
end
end
def fork_danger_3?
DANGEROUS_SITUATIONS_1.detect do |x|
@board[x[0]] != @board[x[2]] &&
@board[x[1]] == @board[x[2]]
end
end
, , , , , AI : 1. , 2. 3. (.. , , , ). , , . , Neural Network.
array_of_games.each do |row|
row.each do |e|
next unless e == current_position
if row[6].to_i - row[3].to_i == 2 && row[4] == 'O' && row[2].to_f != 0.2
unacceptable_moves_array << row[0]
# Find moves that inevitably lead to a fork:
elsif fork_danger_1 && row[3].to_i == 3 && row[0].to_i.odd?
unacceptable_moves_array << row[0]
elsif (fork_danger_2 || fork_danger_3) && row[3].to_i == 3 && row[0].to_i.even?
unacceptable_moves_array << row[0]
end
next if row[5].nil?
# Find moves that may lead to a fork:
array_of_moves_to_fork << row[0] if row[3].to_i == row[5].to_i
# Find attacking moves:
attack_moves_array << row[0] if row[3].to_i == row[5].to_i && row[6].to_i < 7
end
end
, , , AI , . ... , , , , ... , "" . , , - , , ... ? - ", , ", .
array_of_games.each do |row|
row.each do |e|
next unless e == current_position
next if arrays[0].include?(row[0])
unless arrays[1].include?(row[0]) && !arrays[2].include?(row[0])
if row[6].to_i - row[3].to_i == 1
x_data.push([row[0].to_i])
y_data.push([1])
elsif row[6].to_i - row[3].to_i == 3
if arrays[2].include?(row[0])
x_data.push([row[0].to_i])
y_data.push([0.9])
elsif arrays[1].include?(row[0])
x_data.push([row[0].to_i])
y_data.push([0.3])
end
else
x_data.push([row[0].to_i])
y_data.push([row[2].to_f])
end
end
end
:
data = nn_data(board, fork_danger_1, fork_danger_2, fork_danger_3, array_of_games)
fann_results_array = []
train = RubyFann::TrainData.new(inputs: data[0], desired_outputs: data[1])
model = RubyFann::Standard.new(
num_inputs: 1,
hidden_neurons: [4],
num_outputs: 1
)
model.train_on_data(train, 5000, 500, 0.01)
data[0].flatten.each do |i|
fann_results_array << model.run([i])
end
result = data[0][fann_results_array.index(fann_results_array.max)]
: ( csv-) Neural Network .
- , - , . csv- ( , ), . , - - , , .
PS: Der beschriebene Code ist in meinem Github immer vollständig (und nicht fragmentarisch, wie es das Format des Artikels vorschreibt) verfügbar . Natürlich kann jeder einen Git-Klon erstellen und mit dem Code experimentieren oder einfach nur spielen. Ich bin kein Befürworter der Ausführung von Ruby-Anwendungen unter Windows, dies ist keine sehr gute Idee, aber in diesem Fall wird es funktionieren, ich habe es versucht. Vielleicht wird es etwas weniger beeindruckend als in der Linux-Konsole, aber die Logik wird funktionieren.