hkucuk

Tic-Tac-Toe Oyunu GoLang Implementasyonu

23 Haziran 2021 • ☕️ 3 dk okuma • 🏷 bilgisayar, yazılım

Yazar tarafından şu dillere çevrildi: English


Tic-Tac-Toe (bazen X ve O olarak da bilinir), iki oyuncunun kendi sembollerini (X ve O) kullanarak, 3x3’lük tahtada bir satır, sütun veya diagonal çizmeye çalıştığı bir oyundur.

Oyuncular sırayla hamle yaparlar ve kendi sembollerini yatay, dikey ya da çağraz olarak sıralamaya çalışırlar. Sıralayabilen oyunu kazanır ya da oyun berabere sonuçlanır :)

GoLang dilinde tic-tak-toe oyununun konsol üzerinden iki kişi tarafından oynanmasını sağlayan kod aşağıdadır:

package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

const (
	empty = " "
	x     = "X"
	o     = "O"
)

type game struct {
	board [][]string
}

// newGame oluşturulan bir game nesnesi döndürür.
func newGame() *game {
	g := &game{}
	g.board = make([][]string, 3)

	for i := range g.board {
		g.board[i] = make([]string, 3)
		for j := range g.board[i] {
			g.board[i][j] = empty
		}
	}

	return g
}

// playMove bir oyuncunun tahtada yapacağı hamleyi yapar.
func (g *game) playMove(x, y int, player string) error {

	if x < 0 || x > 2 || y < 0 || y > 2 {
		return fmt.Errorf("Invalid move")
	}

	if g.board[x][y] != empty {
		return fmt.Errorf("That space is already taken")
	}

	g.board[x][y] = player
	return nil
}

// drawBoard tahtayı çizmek için kullanılır.
func (g *game) drawBoard() {
	fmt.Println("  0 1 2")
	for i, row := range g.board {
		fmt.Printf("%d ", i)
		fmt.Println(strings.Join(row, "|"))
	}
}

// checkWin kazananın olup olmadığını kontrol eder.
func (g *game) checkWin() string {
	// Check rows
	for _, row := range g.board {
		if row[0] != empty && row[0] == row[1] && row[1] == row[2] {
			return row[0]
		}
	}

	// Check columns
	for i := 0; i < 3; i++ {
		if g.board[0][i] != empty && g.board[0][i] == g.board[1][i] && g.board[1][i] == g.board[2][i] {
			return g.board[0][i]
		}
	}

	// Check diagonals
	if g.board[0][0] != empty && g.board[0][0] == g.board[1][1] && g.board[1][1] == g.board[2][2] {
		return g.board[0][0]
	}

	if g.board[0][2] != empty && g.board[0][2] == g.board[1][1] && g.board[1][1] == g.board[2][0] {
		return g.board[0][2]
	}

	return empty
}

func main() {
	g := newGame()
	reader := bufio.NewReader(os.Stdin)

	fmt.Println("Welcome to Tic-Tac-Toe!")
	fmt.Println("Player 1 is X and Player 2 is O")
	fmt.Println("Enter your moves in the format 'x y' (without quotes)")

	for i := 0; i < 9; i++ {
		player := x

		if i%2 == 1 {
			player = o
		}

		fmt.Printf("Player %s's turn: ", player)
		text, _ := reader.ReadString('\n')
		text = strings.TrimSpace(text)
		parts := strings.Split(text, " ")

		if len(parts) != 2 {
			fmt.Println("Invalid input")
			i--
			continue
		}

		x, err := strconv.Atoi(parts[0])
		if err != nil {
			fmt.Println("Invalid input")
			i--
			continue
		}

		y, err := strconv.Atoi(parts[1])
		if err != nil {
			fmt.Println("Invalid input")
			i--
			continue
		}

		err = g.playMove(x, y, player)
		if err != nil {
			fmt.Println(err)
			i--
			continue
		}

		g.drawBoard()

		winner := g.checkWin()
		if winner != empty {
			fmt.Printf("Player %s wins!\n", winner)
			break
		}
	}

	if g.checkWin() == empty {
		fmt.Println("It's a draw!")
	}
}

Program çalıştırıldığında aşağıdaki gibi bir çıktı verecektir. Oyuncular hamlelerini yapmak için konsola koordinatları girerler. Örneğin, bir oyuncu (X) tahtadaki (0, 1) noktasına hamle yapmak isterse, “0 1” (boşluklu ve tırnaksız) şeklinde bir girdi yapar. Tahta güncellenir ve sıradaki oyuncu hamle yapmaya çalışır. Oyun devam eder ve eğer bir oyuncu üç sembolünü tahtada çizerek kazanırsa veya tüm kareler dolup oyun berabere biterse oyun sona erer.

Örnek oyun

> go run main.go                   
Welcome to Tic-Tac-Toe!
Player 1 is X and Player 2 is O
Enter your moves in the format 'x y' (without quotes)

Player X's turn: 0 1
  0 1 2
0  |X| 
1  | | 
2  | | 

Player O's turn: 1 1
  0 1 2
0  |X| 
1  |O| 
2  | | 

Player X's turn: 2 0
  0 1 2
0  |X| 
1  |O| 
2 X| | 

Player O's turn: 0 0
  0 1 2
0 O|X| 
1  |O| 
2 X| | 

Player X's turn: 2 1
  0 1 2
0 O|X| 
1  |O| 
2 X|X| 

Player O's turn: 2 2
  0 1 2
0 O|X| 
1  |O| 
2 X|X|O

Player O wins!

Kaynaklar