Ich habe @ kei011s "○ ✕ Spiel" gesehen. Der Zweck von Anfängern ist es, ein Programm zu absolvieren, das selbstständig funktioniert. Es ist also großartig, dies zu erreichen und die Ergebnisse zu veröffentlichen.
Ich war jedoch enttäuscht, dass der Programmcode Anfängern gemeinsam ist.
Ich habe mich umgestaltet, während ich mir der Objektorientierung bewusst war. Ich selbst überarbeite durch Versuch und Irrtum. Wenn Sie also andere gute Ideen haben, würde ich mich freuen, wenn Sie einen Kommentar abgeben könnten.
Listen Sie zunächst die Dinge und Akteure auf, die im "○ ✕ Spiel" erscheinen.
Geben Sie jeden ein.
Außerdem habe ich die Zeichenkette string_t und die Position point_t, an der der Stein platziert ist, eingegeben.
Hier ist der überarbeitete Quellcode der C-Sprache.
tictactoe.c
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <time.h>
#ifdef __GNUC__
#define scanf_s scanf
#endif
#define SIZE (3) //Brettgröße (vertikal)=Seite)
typedef enum {
SPACE = '-', //Wert, wenn kein Stein auf dem Brett ist
STONE_A = 'A',
STONE_B = 'B',
} stone_t; //Stein zum Anbringen auf dem Brett
typedef stone_t board_t[SIZE][SIZE]; //Tafel
typedef int point_t; //Board xy Position(0 ~ STEP-1)
typedef int step_t; //Unterschied aktualisieren
typedef const char *string_t; //String
typedef struct player player_t; //Spieler (Menschen und Computer)
struct player {
string_t name;
stone_t stone;
string_t order;
void (*play)(player_t *player, board_t board);
player_t *opponent;
};
//Board-Anzeige
void show(board_t board)
{
printf("★ Aktuelle Tabelle ★\n"
"\n x");
for (point_t x = 0; x < SIZE; x++) {
printf(" %2d", x);
}
printf("\n y -");
for (point_t x = 0; x < SIZE; x++) {
printf("---");
}
for (point_t y = 0; y < SIZE; y++) {
printf("\n%2d| ", y);
for (point_t x = 0; x < SIZE; x++) {
printf(" %c ", board[y][x]);
}
}
printf("\n");
}
//Stimmt, wenn es einen Platz auf dem Brett gibt
bool space(board_t board)
{
for (point_t y = 0; y < SIZE; y++) {
for (point_t x = 0; x < SIZE; x++) {
if (board[y][x] == SPACE) {
return true;
}
}
}
return false;
}
//Gibt true zurück, wenn der angegebene Stein dem Brett folgt und die Zeile vollständig ist
bool follow(board_t board, stone_t stone, point_t y, point_t x, step_t dy, step_t dx)
{
for (step_t i = 1; i < SIZE; i++) {
y = (y + dy + SIZE) % SIZE;
x = (x + dx + SIZE) % SIZE;
if (board[y][x] != stone) {
return false;
}
}
return true;
}
//Wenn die Linie auf dem Brett mit dem angegebenen Stein abgeschlossen ist*py, *Setze px und gib true zurück
bool line(board_t board, stone_t first, stone_t other, point_t *py, point_t *px) {
const step_t INCRESE_Y = 1, INCRESE_X = 1, DECRESE_X = -1, STAY_Y = 0, STAY_X = 0;
for (point_t y = 0; y <SIZE ; y++) {
for (point_t x = 0; x < SIZE; x++) {
if (board[y][x] == first &&
(follow(board, other, y, x, STAY_Y, INCRESE_X) || //Seite
follow(board, other, y, x, INCRESE_Y, STAY_X))) { //Vertikal
*py = y, *px = x;
return true;
}
}
point_t x = y;
if (board[y][x] == first &&
follow(board, other, y, x, INCRESE_Y, INCRESE_X)) { //Unten rechts
*py = y, *px = y;
return true;
}
x = SIZE - 1 - y;
if (board[y][x] == first &&
follow(board, other, y, x, INCRESE_Y, DECRESE_X)) { //Unten links
*py = y, *px = x;
return true;
}
}
return false;
}
//Wenn Sie in Reichweite sind*px, *Setze py und gib true zurück
bool reach(board_t board, stone_t stone, point_t *py, point_t *px)
{
return line(board, SPACE, stone, py, px);
}
//Gibt true zurück, wenn sich der Bingo-Status befindet
bool bingo(board_t board, stone_t stone)
{
point_t y, x;
return line(board, stone, stone, &y, &x);
}
//Positionseingabe
point_t input(player_t *player, string_t target)
{
printf("%s:%s(%c)von%Geben Sie s ein:", player->order, player->name, player->stone, target);
point_t point;
switch (scanf_s("%d", &point)) {
case EOF:
exit(1);
case 1:
if (0 <= point && point < SIZE) {
return point;
}
break;
default:
scanf("%*s"); //Eingabe verwerfen
}
printf("Der Wert ist falsch.\n\n");
return -1;
}
//Menschen spielen(Mach einen Schritt)
void human(player_t *player, board_t board)
{
while (true) {
point_t x = input(player, "Seite(x)");
if (x < 0) continue;
point_t y = input(player, "Vertikal(y)");
if (y < 0) continue;
if (board[y][x] == SPACE) {
board[y][x] = player->stone;
return;
}
printf("Die angegebene Position ist falsch.\n\n");
}
}
//Computer spielt(Mach einen Schritt)
void computer(player_t *player, board_t board)
{
point_t y, x;
if (reach(board, player->stone, &y, &x)) {
//Wählen Sie Ihre Reichweite
} else if (reach(board, player->opponent->stone, &y, &x)) {
//Beeinträchtigen Sie die Reichweite des Gegners
} else {
y = 1, x = 1; //Mitte
while (board[y][x] != SPACE) {
y = rand() % SIZE, x = 0;
while (x < SIZE - 1 && board[y][x] != SPACE) {
x++;
}
}
}
board[y][x] = player->stone;
}
//SIZE Alignment-Spiel
void game()
{
player_t player1 = { "Sie", STONE_A, "Erstschlag", human },
player2 = { "Computer", STONE_B, "Zweiter Angriff", computer },
*player = &player1;
player1.opponent = &player2;
player2.opponent = &player1;
board_t board;
for (point_t y = 0; y < SIZE; y++) {
for (point_t x = 0; x < SIZE; x++) {
board[y][x] = SPACE;
}
}
show(board);
while (space(board)) {
player->play(player, board);
show(board);
if (bingo(board, player->stone)) {
printf("%s Sieg!\n", player->name);
return;
}
player = player->opponent;
}
printf("zeichnen!\n");
}
int main(void)
{
srand((unsigned int)time(NULL));
game();
return 0;
}
"Mr. Board, sind Sie irgendwo?" "Mr. Board, sind diese drei Steine in einer Reihe?" "Du, bitte mach einen Zug" "Computer, mach einen Schritt" Wenn Sie darüber nachdenken, wen Sie fragen, wird "who" als Variablenname und erstes Argument der Funktion verwendet.
Ich habe versucht, den Quellcode der C-Sprache in die objektorientierte Sprache Python zu portieren. Wenn Sie die Sprache C lesen können, können Sie Python so lesen, wie es ist.
"Wer" ist als Klasse definiert.
Jede Funktion ist einer Klasse zugeordnet, die berücksichtigt, wer der Job ist.
Da "who" aus der Klasse betrachtet "self" ist, ist das erste Argument der Variablenname self.
Wenn Sie eine Funktion in einer Klasse aufrufen möchten, schreiben Sie in der Reihenfolge "who.function name (argument)
", und sie wird in der entsprechenden Klasse in "who, argument) "konvertiert und aufgerufen. .. Also lass dich selbst das erste Argument sein. Wenn Sie einen Python3-Interpreter haben, können Sie ihn ausführen, indem Sie an der Eingabeaufforderung
python tictactoe.py` eingeben.
Ich wollte die C-Sprache so lassen, wie sie ist, deshalb vermeide ich Python-ähnliches Schreiben so weit wie möglich.
tictactoe.py
from random import randint
SPACE = '-' #Wert, wenn kein Stein auf dem Brett ist
class Board(list): # typedef char board_t[3][3]; (Liste ist ein Array)
#Board-Initialisierung (spezieller Name von Python festgelegt)
def __init__(self):
super().__init__([ [ SPACE, SPACE, SPACE ],
[ SPACE, SPACE, SPACE ],
[ SPACE, SPACE, SPACE ] ])
#Board-Anzeige
def show(self): # void show(board_t board)
print("★ Aktuelle Tabelle ★\n\n"
" x 0 1 2\n"
" y -------")
for y in range(3):
print(" %d| %c %c %c" % (y, self[y][0], self[y][1], self[y][2]))
#Geben Sie true zurück, wenn sich ein Platz auf dem Brett befindet
def space(self): # bool_t space(board_t board)
for y in range(3):
for x in range(3):
if self[y][x] == SPACE:
return True
return False
#Gibt die Koordinaten zurück, wenn die angegebenen drei Steine auf dem Brett ausgerichtet sind. Keine, wenn sie nicht ausgerichtet sind
def line(self, stone1, stone2, stone3): #Python kann mehrere Werte als Rückgabewerte zurückgeben>Argumentreduktion mit
for y in range(3):
for x in range(3):
if (self[y][x] == stone1 and
((self[y][(x + 1) % 3] == stone2 and #Seite an Seite
self[y][(x + 2) % 3] == stone3) or
(self[(y + 1) % 3][x] == stone2 and #Vertikal
self[(y + 2) % 3][x] == stone3))):
return (y, x)
if (self[(y + 0) % 3][(y + 0) % 3] == stone1 and #Unten rechts
self[(y + 1) % 3][(y + 1) % 3] == stone2 and
self[(y + 2) % 3][(y + 2) % 3] == stone3):
return (y, y)
if (self[(y + 0) % 3][(2 - y + 3) % 3] == stone1 and #Unten links
self[(y + 1) % 3][(1 - y + 3) % 3] == stone2 and
self[(y + 2) % 3][(0 - y + 3) % 3] == stone3):
return (y, (2 - y + 3) % 3)
return None
#Gibt die Position zurück, wenn erreicht, Keine, wenn nicht
def reach(self, stone):
return self.line(SPACE, stone, stone)
#Gibt true zurück, wenn sich der Bingo-Status befindet
def bingo(self, stone):
return self.line(stone, stone, stone) is not None
class Player:
def __init__(self, name, stone, order):
self.name = name
self.stone = stone
self.order = order
class Human(Player):
#Positionseingabe
def input(self, target):
try:
point = int(input("%s:%s(%c)von%Geben Sie s ein:" % (self.order, self.name, self.stone, target)))
if 0 <= point <= 2:
return point
except ValueError:
pass
print("Der Wert ist falsch.\n")
return -1
#Spielen(Mach einen Schritt)
def play(self, board):
while True:
x = self.input("Seite(x)")
if x < 0: continue
y = self.input("Vertikal(y)")
if y < 0: continue
if board[y][x] == SPACE:
board[y][x] = self.stone
return
print("Die angegebene Position ist falsch.\n")
class Computer(Player):
#Spielen(Mach einen Schritt)
def play(self, board):
position = board.reach(self.stone) #Ihre Reichweite Wahl
if position is None:
position = board.reach(self.opponent.stone) #Beeinträchtigung der Reichweite der anderen Partei
if position is None:
y, x = 1, 1 #Mitte
while board[y][x] != SPACE:
y, x = randint(0, 2), 0
while x < 2 and board[y][x] != SPACE:
x += 1
position = (y, x)
y, x = position
board[y][x] = self.stone
#Dreiäugiges Spiel
def main():
player1 = Human("Sie", 'A', "Erstschlag")
player2 = Computer("Computer", 'B', "Zweiter Angriff")
player = player1
player1.opponent = player2
player2.opponent = player1
board = Board()
board.show()
while board.space():
player.play(board)
board.show()
if board.bingo(player.stone):
print("%s Sieg!" % player.name)
return
player = player.opponent
print("zeichnen!")
return
if __name__ == '__main__':
main()
Recommended Posts