Trò chơi Tic-tac-toe


15

Tạo một chương trình xác định để chơi n d tic-tac-toe với các thí sinh khác.

Chương trình của bạn sẽ hoạt động khi n(chiều rộng) và d(số thứ nguyên) nằm trong các phạm vi sau:

n∈[3,∞)∩ℕ  ie a natural number greater than 2
d∈[2,∞)∩ℕ  ie a natural number greater than 1

n = 3; d = 2(3 2 tức là 3 bằng 3):

[][][]
[][][]
[][][]

n = 3; d = 3(3 3 tức là 3 bằng 3 bởi 3):

[][][]
[][][]
[][][]

[][][]
[][][]
[][][]

[][][]
[][][]
[][][]

n = 6; d = 2(6 2 tức là 6 bằng 6):

[][][][][][]
[][][][][][]
[][][][][][]
[][][][][][]
[][][][][][]
[][][][][][]

Và như thế.

Đầu vào:

Đầu vào sẽ là STDIN. Dòng đầu tiên sẽ là hai số ndở dạng n,d.

Sau đó sẽ là một dòng bao gồm các tọa độ chỉ định các di chuyển đã được thực hiện. Các tọa độ sẽ được liệt kê dưới dạng : 1,1;2,2;3,3. Góc trên bên trái là gốc (0,0 cho 2D). Trong trường hợp chung, danh sách này sẽ giống như 1,2,...,1,4;4,0,...,6,0;...trong đó số thứ nhất đại diện cho bên trái, bên phải thứ hai, thứ ba đến thứ ba, v.v. Lưu ý rằng tọa độ đầu tiên là Xlần đầu tiên, lần thứ hai là Olượt đầu tiên, ....

Nếu đây là lần di chuyển đầu tiên, đầu vào sẽ có một số theo sau là 1 dòng trống.

Để thống nhất, đầu vào sẽ luôn kết thúc bằng một dòng mới. Đầu vào mẫu (\ n là dòng mới):

10,10\n0,0,0,0,0,0,0,0,0,0;0,2,3,4,5,6,7,8,9,0;0,1,2,3,4,5,6,7,8,9\n

Đối với di chuyển đầu tiên:

10,10\n\n

nơi \nlà kí tự xuống dòng.

Đầu ra:

Xuất di chuyển mà bạn muốn thực hiện ở định dạng giống như đầu vào (danh sách được phân tách bằng dấu phẩy). Di chuyển không hợp lệ (nghĩa là một động thái đã được thực hiện) sẽ dẫn đến thua lỗ cho trò chơi.

Lưu ý: Bạn có thể sử dụng một trình tạo số ngẫu nhiên, miễn là bạn gieo nó với một giá trị sao cho mỗi lần chạy sẽ giống hệt nhau với cùng điều kiện. Nói cách khác, chương trình phải có tính quyết định.

Lưu ý: chỉ cho phép di chuyển hợp lệ.

Trò chơi chiến thắng (Nếu bạn đã chơi đủ đa chiều tic tac toe, điều này là như nhau.)

Để có được chiến thắng, một người chơi phải có tất cả các ô vuông liền kề dọc theo một hàng. Đó là, người chơi đó phải ndi chuyển trên một dòng để trở thành người chiến thắng.

Liền kề:

  • mỗi ô là một điểm; ví dụ (0,0,0,0,0) là một điểm trongd=5
  • gạch liền kề là gạch sao cho cả hai đều trên cùng một khối d-cube. Nói cách khác, khoảng cách Ch Quashev giữa các ô là 1.
  • nói cách khác, nếu một điểm ptiếp giáp với một điểm q, thì mọi tọa độ trong ps tọa độ tương ứng sẽ qkhác nhau không quá một điểm. Ngoài ra, ít nhất trên cặp tọa độ khác nhau bởi chính xác một.

Dòng:

  • Các dòng được xác định bởi các vectơ và gạch. Một dòng là mỗi ô được đánh bởi phương trình:p0 + t<some vector with the same number of coordinates as p0>

Điều kiện mô phỏng và chiến thắng:

  • Nhà nước trong câu trả lời của bạn nếu nó đã sẵn sàng để chấm điểm. Đó là, chỉ rõ rằng câu trả lời của bạn đã được thực hiện hay chưa.

  • Nếu câu trả lời của bạn được đánh dấu là xong, nó sẽ không được chấm điểm cho đến ít nhất 24 giờ sau lần chỉnh sửa cuối cùng thành mã.

  • Các chương trình phải hoạt động ngoại tuyến. Nếu một chương trình bị phát hiện là gian lận, nó sẽ tự động nhận được điểm -1và sẽ không được ghi thêm. (Làm thế nào bất cứ ai sẽ kết thúc với chương trình gian lận của họ?)

  • Nếu chương trình của bạn tạo đầu ra không hợp lệ, nó ngay lập tức được tính là tổn thất cho trò chơi

  • Nếu chương trình của bạn không tạo được kết quả đầu ra sau 1 phút, nó ngay lập tức được tính là tổn thất cho trò chơi. Nếu cần thiết, tối ưu hóa cho tốc độ. Tôi không muốn phải đợi một giờ để kiểm tra chương trình này.

  • Mỗi chương trình sẽ được chạy với các chương trình khác hai lần cho mỗi ntrong phạm vi [3,6]và mỗi chương trình dtrong phạm vi [2,5], một lần Xvà một lần như O. Đây là một vòng.

  • Đối với mỗi trò chơi, một chương trình sẽ thắng, nó đạt được +3điểm số của nó. Nếu chương trình bị ràng buộc (1 thắng và 1 thua trong một vòng duy nhất hoặc ràng buộc cho cả hai trò chơi), thì nó sẽ được +1. Nếu chương trình bị mất, thì nó sẽ nhận được +0(tức là không thay đổi).

  • Chương trình có số điểm cao nhất sẽ thắng. Nếu có hòa, thì chương trình có số trận thua ít nhất (trong số các thí sinh bị trói) sẽ thắng.

Lưu ý: Tùy thuộc vào số lượng câu trả lời, tôi có thể cần trợ giúp để chạy các bài kiểm tra.

Chúc may mắn! Và có thể các mô phỏng chạy bao giờ có lợi cho bạn!


Win-checker thách thức. <---- Thử thách này là tạo ra các chương trình để kiểm tra xem một trò chơi nào đó có chiến thắng không. Nó rất liên quan đến thử thách này.
Justin

Thẻ độc lập mà bạn vừa phát minh không thêm bất cứ thứ gì vào phân loại thẻ. Tôi nghĩ bạn nên loại bỏ nó.
Howard

@Howard Được rồi. Tôi nhận thấy rằng rất nhiều câu hỏi có hạn chế đó, vì vậy tôi nghĩ rằng một thẻ sẽ phù hợp.
Justin

4
Một trò chơi lạ. Động thái chiến thắng duy nhất là không chơi.
German_guy

(w, x, y, z) là định dạng đầu ra hợp lệ?
alexander-brett

Câu trả lời:


2

Con trăn 3

import random as rand
import re

def generateMoves(width, dim):
    l = [0] * dim
    while existsNotX(l, width - 1):
        yield l[:]
        for i in range(dim):
            if l[i] < width - 1:
                l[i] += 1
                break
            else:
                l[i] = 0
    yield l

def existsNotX(l, x):
    for i in l:
        if i != x:
            return True
    return False

input_s = input()
dims, moves = None, None
#this is to allow input as a single paste, instead of ENTER inputting.
try:
    dims, moves = input_s.splitlines()
except ValueError:
    dims = input_s
    moves = input()

rand.seed(moves + dims)

dims = eval(dims) #change into tuple

moves = moves.split(';')
if len(moves[0]):
    moves = [eval(m) for m in moves] #change into tuples

output =[x for x in generateMoves(dims[0], dims[1]) if x not in moves]
print(re.sub('[^\\d,]', '', str(output[rand.randint(0, len(output))])))

Đây chỉ đơn giản là một ai ngẫu nhiên. Nó chọn ngẫu nhiên một di chuyển ra khỏi các di chuyển vẫn còn có sẵn.


2

Python 2.7

Đây là một bài nộp đang thực hiện mà tôi đang cung cấp để cung cấp bộ xương / cảm hứng cho những người trả lời khác. Nó hoạt động bằng cách liệt kê tất cả các dòng chiến thắng có thể, sau đó áp dụng một số heuristic để ghi điểm đó theo mức độ có giá trị của nó. Hiện tại, heuristic là trống (hoạt động siêu bí mật). Tôi cũng đã thêm xử lý lỗi win và clash.

Ghi chú về vấn đề

Có bao nhiêu dòng chiến thắng là có? Xem xét trường hợp 1 chiều; có 2 đỉnh, 1 cạnh và 1 đường. Trong 2 chiều, chúng ta có 4 đỉnh được nối bởi 2 dòng và 4 cạnh được nối bởi 2 * n dòng. Trong 3 chiều, chúng ta có 8 đỉnh được nối bởi 4 đường, 12 cạnh được nối bởi 6 * n đường và 6 mặt được nối bởi3*n^2 các đường.

Nói chung, chúng ta hãy gọi một đỉnh là 0 mặt, cạnh 1 mặt, v.v ... Sau đó, hãy N(i)biểu thị số mặt i, dsố kích thước và nchiều dài cạnh. Sau đó, số dòng chiến thắng là0.5*sum(N(i)*n^i,i=0..d-1) .

Theo wikipedia, N(i)=2^(d-i)*d!/(i!*(n-1)!)vì vậy công thức cuối cùng là:

sum(2^(d-i-1) n^i d! / (i! * (n-i)!),i=0..d-1)

mà wolfram | alpha không thích lắm. Điều này trở nên rất lớn khá nhanh, vì vậy tôi không hy vọng chương trình của mình có thời gian chạy có thể quản lý được cho d> 8.

Một số kết quả (xin lỗi về định dạng:

d\n 0   1    2      3      4       5        6        7         8         9
0   1   1    1      1      1       1        1        1         1         1
1   2   4    6      8      10      12       14       16        18        20
2   4   11   26     47     74      107      146      191       242       299
3   8   40   120    272    520     888      1400     2080      2952      4040
4   16  117  492    1437   3372    6837     12492    21117     33612     50997
5   32  364  2016   7448   21280   51012    107744   206896    368928    620060
6   64  1093 8128   37969  131776  372709   908608   1979713   3951424   7352101
7   128 3280 32640  192032 807040  2687088  7548800  18640960  41611392  85656080
8   256 9834 130809 966714 4907769 19200234 62070009 173533434 432891129 985263594

Tôi / O

Hiện tại, đầu vào cần phải được nhập là: tictactoe.py <ret> n,d <ret> move;move <ret>- lưu ý nhiều dòng và không có dòng cuối cùng; .

Đầu ra trông giống như (x_1,x_2,x_3...), ví dụ:

tictactoe.py <ret> 6,5 <ret> <ret> => 0, 0, 0, 0, 0

tictactoe.py <ret> 6,5 <ret> 0,0,0,0,0;0,0,0,0,5 <ret> => 0, 0, 0, 5, 0

# Notes on terminology:
#
# - A hypercube is the region [0,n]^d
# - An i-facet is an i-dimensional facet of a hypercube,
#   which is to say, a 0-facet is a vertex, a 1-facet an
#   edge, a 2-facet a face, and so on.
# - Any tuple {0,n}^i is a vertex of an i-hypercube
#   which is why I've used vertex to describe such
#   tuples
# - A winning line is a set of n coordinates which joins
#   two opposite i-facets
# - i-facets are opposite if they differ in every co-
#   ordinate which defines them
#
# Test Data:
#  


import numpy
import itertools

def removeDuplicates(seq):
    noDupes = []
    [noDupes.append(i) for i in seq if not noDupes.count(i)]
    return noDupes 


def listPairedVertices (i,n):
    """
    listPairedVertices returns a list L of elements of {0,n}^i which has the
    property that for every l in L, there does not exist l' such that
    l+l' = {n}^i.
    """

    vertices = numpy.array([[b*(n-1)  for b in a] for a in [
        list(map(int,list(numpy.binary_repr(x,i)))) for x in range(2**i)
    ]])
    result = []
    while len(vertices)>1:
        for j in range(len(vertices)):
            if numpy.all(vertices[j] + vertices[0] == [n-1]*i):
                result.append(vertices[0])
                vertices=numpy.delete(vertices,[0,j],axis=0)
                break
    return result


def listSequences (d,l):
    """
    listSequences returns the subset of {0,1}^d having precisely n 1s.
    """
    return numpy.array([
        r for r in itertools.product([0,1],repeat=d) if sum(r)==l
    ])


def listPaddedConstants (s,n):
    """
    listPaddedConstants takes a sequence in {0,1}^d and returns a number in
    {0..n}^sum(s) padded by s
    """
    result = numpy.zeros([n**sum(s),len(s)],dtype=numpy.int)
    for i,x in enumerate([list(z) for z in 
        itertools.product(range(n),repeat=sum(s))]):
        for j in range(len(s)):
            if s[j]: result[i][j] = x.pop()
    return result


def listWinningVectorsForDimension(d,i,n):
    """
    List the winning lines joining opposite i-facets of the hypercube.

    An i-facet is defined by taking a vertex v and a sequence s, then forming 
    a co-ordinate C by padding v with zeroes in the positions indicated by s.
    If we consider s = s_0.e_0 + s_1+e_1... where the e_j are the canonical
    basis for R^d, then the formula of the i-facet is 
        C+x_0.s_0.e_0+x_1.s_1.e_1... 
    for all vectors x = (x_0,x_1...) in R^n

    We know that winning lines only start at integral positions, and that the
    value of a will only be needed when s_j is nonempty, so the start point S
    of a winning line is in fact determined by:
     + vertex v in {0,n}^(d-i), padded by s
     + a in R^i, padded by the complement of s, s'

    Having performed the following operations, the co-ordinates of the winning
    lines are abs(S-k*s') for k in [0..n-1]
    """
    vertices = listPairedVertices(d-i,n)
    sequences = listSequences(d,i)
    result = []
    for s in sequences:
        for v in vertices:
            C = [0]*d
            j = 0
            for index in range(d):
                if s[index]: C[index] = 0
                else: 
                    C[index] = v[j]
                    j+=1
            result += [
                [numpy.absolute(S-k*(numpy.absolute(s-1))) for k in range(n)] 
                    for S in [C+a for a in listPaddedConstants(s,n)]
            ]
    return result


def AllWinningLines (d,n):
    """
    has the structure [[x_1,x_2,x_3],[y_1,y_2,y_3]] where each l_k is a
    length-d co-ordinate
    """
    result = []
    for i in range(d):
        result += listWinningVectorsForDimension(d,i,n)
    return result


def movesAlreadyMade ():
    """
    Returns a list of co-ordinates of moves already made read from STDIN
    """
    parameters = raw_input()
    moves = raw_input()
    parameters = list(map(int,parameters.split(',')))
    moves = [map(int,a.split(',')) for a in moves.split(';')] \
        if moves != '' else []
    return {'n':parameters[0], 'd':parameters[1], 'moves':moves}

def scoreLine (moves, line, scores, n):
    """
    Gives each line a score based on whatever logic I choose
    """
    myMoves          = moves[0::2]
    theirMoves       = moves[1::2]
    if len(moves)%2: myMoves, theirMoves = theirMoves, myMoves

    lineHasMyMove    = 0
    lineHasTheirMove = 0
    score            = 0

    for coord in line:
        if coord.tolist() in myMoves: 
            lineHasMyMove += 1
            if coord.tolist() in theirMoves: raise Exception('Move clash')
        elif coord.tolist() in theirMoves: lineHasTheirMove += 1

    if lineHasMyMove == len(line):
        raise Exception('I have won')
    elif lineHasTheirMove == len(line):
        raise Exception('They have won')
    elif lineHasMyMove and lineHasTheirMove: 
        pass
    elif lineHasTheirMove == len(line)-1: 
        score = n**lineHasTheirMove
    else: 
        score = n**lineHasMyMove

    for coord in line:
        if coord.tolist() not in moves: 
            scores[tuple(coord)]+=score

def main():
    """
    Throw it all together
    """
    data      = movesAlreadyMade()
    dimension = data['d']
    length    = data['n']
    lines     = AllWinningLines(dimension, length)
    scores    = numpy.zeros([length]*dimension, dtype=numpy.int)

    try: [scoreLine(data['moves'], line, scores, length) for line in lines]
    except Exception as E:
            print 'ERROR: ' + E.args[0]
            return
    print ','.join(map(
        str,numpy.unravel_index(numpy.argmax(scores),scores.shape)
        ))


if __name__ == "__main__": main() 

Chỉnh sửa: cho I / O, thêm logic. Tôi tin rằng điều này đã sẵn sàng để đánh dấu

Lưu ý rằng nhận xét này ban đầu là một trình giữ chỗ mà tôi đã xóa và không xóa.


1

Con trăn 2

import re
import itertools

input_s = raw_input()
dims, moves = None, None
#this is to allow input as a single paste, instead of ENTER inputting.
try:
    dims, moves = input_s.splitlines()
except ValueError:
    dims = input_s
    moves = raw_input()

dims = eval(dims) #change into tuple

moves = moves.split(';')
if len(moves[0]):
    moves = [eval(m) for m in moves] #change into tuples

allSpaces = [x for x in itertools.product(range(dims[0]), repeat=dims[1])]
move = None
for space in allSpaces:
    if space not in moves:
        move = space
        break
print(re.sub('[^\\d,]', '', str(move)))

Hầu hết các mã giống hệt như AI ngẫu nhiên của Quincunx . Thay vì chọn ngẫu nhiên một di chuyển, nó chọn di chuyển có sẵn đầu tiên theo từ vựng (nghĩa là (0,0, ... 0), sau đó (0,0, ... 1), sau đó (0,0, ... 2) , Vân vân.).

Đây là một chiến lược rác rưởi, nhưng nó hầu như luôn luôn chơi ngẫu nhiên.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.