틱택 토 게임


15

N 놀 결정 생성 프로그램 (D)의 다른 참가자와 틱택 토한다.

n(너비) 및 d(치수)가 다음 범위에 있을 때 프로그램이 작동해야 합니다.

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

n = 3; d = 2(3 2 즉 3 x 3) :

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

n = 3; d = 3(3 3 즉 3 by 3 by 3) :

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

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

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

n = 6; d = 2(6 2 즉 6 x 6) :

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

등등.

입력:

입력은 STDIN입니다. 입력의 첫 번째 라인은 두 수있을 것이다 nd형태 n,d.

그 후에 행해진 이동을 지정하는 좌표로 구성된 선이됩니다. 좌표는 다음 형식으로 표시됩니다 1,1;2,2;3,3. 왼쪽 상단이 원점입니다 (2D의 경우 0,0). 일반적인 경우,이 목록은 1,2,...,1,4;4,0,...,6,0;...첫 번째 숫자가 왼쪽-오른쪽, 두 번째 위-아래, 3-3 차원 등을 나타내는 위치와 같습니다. 첫 번째 좌표는 X첫 번째 회전이고 두 번째는 이다 O최초의 회전, ...

이것이 첫 번째 이동 인 경우 입력은 숫자 다음에 1 개의 빈 줄이옵니다.

일관성을 위해 입력은 항상 줄 바꿈으로 끝납니다. 샘플 입력 (\ n은 줄 바꿈) :

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

첫 번째 이동의 경우 :

10,10\n\n

\n개행 문자는 어디에 있습니까 ?

산출:

입력과 같은 형식으로 쉼표로 구분 된 이동을 출력하십시오. 유효하지 않은 이동 (즉 이미 수행 된 이동)은 게임에서 손실됩니다.

참고 : 동일한 조건에서 각 실행이 동일하도록 값으로 시드하는 한 난수 생성기를 사용할 수 있습니다. 다시 말해, 프로그램은 결정 론적이어야합니다.

참고 : 유효한 이동 만 허용됩니다.

승리 게임 (충분히 다차원 틱택 토를 연주 한 경우에도 마찬가지입니다.)

승리하기 위해서는 한 선수가 라인을 따라 인접한 모든 사각형을 가져야합니다. 즉, 해당 플레이어는 n승자가 되려면 한 줄로 이동 해야합니다 .

인접 :

  • 각 타일은 점입니다. 예를 들어 (0,0,0,0,0)은d=5
  • 인접한 타일들은 타일들이 같은 유닛 d- 큐브상의 두 지점들입니다. 즉, 타일 ​​사이의 체비 쇼프 거리는 1입니다.
  • 다시 말해서, 점이 점 p에 인접하면, 대응하는 좌표의 q모든 좌표는 1만큼 차이가 없습니다. 또한 적어도 좌표 쌍이 정확히 하나 다릅니다.pq

윤곽:

  • 선은 벡터와 타일로 정의됩니다. 라인은 방정식에 의해 적중되는 각 타일입니다.p0 + t<some vector with the same number of coordinates as p0>

시뮬레이션 및 승리 조건 :

  • 채점 할 준비가 되었으면 답변하십시오. 즉, 답변이 완료되었는지 여부를 명확하게 표시하십시오.

  • 답변이 완료로 표시되면 코드를 마지막으로 편집 한 후 24 시간 이상이 될 때까지 채점되지 않습니다.

  • 프로그램은 오프라인에서 작동해야합니다. 프로그램이 부정 행위를하는 것으로 밝혀지면 자동으로 점수를 받고 -1더 이상 점수를받지 않습니다. (어떻게 누군가가 프로그램 속임수로 끝날 것입니까?)

  • 프로그램이 유효하지 않은 출력을 생성하면 즉시 게임 손실로 계산됩니다

  • 1 분 후에 프로그램이 출력을 생성하지 못하면 즉시 게임 손실로 계산됩니다. 필요한 경우 속도를 최적화하십시오. 다른 프로그램을 테스트하기 위해 한 시간을 기다릴 필요는 없습니다.

  • 각 프로그램은 두 번 각각 다른 프로그램에 대해 실행됩니다 n범위의 [3,6]d범위에 [2,5]한 번씩, X한 번으로 O. 이것은 한 라운드입니다.

  • 프로그램이 승리 할 때마다 +3점수를 얻 습니다. 프로그램이 묶인 경우 (단일 라운드에서 한 번의 승리와 한 번의 손실 또는 두 게임 모두에서 1 손실) 1을 얻습니다 +1. 프로그램이 손실되면 +0변경 사항이 없습니다.

  • 가장 높은 점수를받은 프로그램이 승리합니다. 동점이 있다면, 가장 적은 수의 잃어버린 게임을 가진 프로그램 (동점 참가자 중)이 이깁니다.

참고 : 답변 수에 따라 테스트 실행에 도움이 필요할 수 있습니다.

행운을 빕니다! 그리고 시뮬레이션이 당신에게 유리하게 실행될 수 있습니다!


승리 검사기 도전. <----이 과제는 특정 게임에서 이겼는지 확인하는 프로그램을 만드는 것입니다. 이 도전과 매우 관련이 있습니다.
Justin

자체에 포함 된 당신은 단지 발명 태그는 태그 분류에 아무것도 추가하지 않습니다. 나는 당신이 그것을 제거해야한다고 생각합니다.
Howard

@Howard 좋아. 많은 질문에 그 제한이 있다는 것을 알았으므로 태그가 적합하다고 생각했습니다.
Justin

4
이상한 게임. 유일한 승리의 움직임은 플레이하지 않는 것입니다.
german_guy

(w, x, y, z)가 유효한 출력 형식입니까?
alexander-brett

답변:


2

파이썬 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))])))

이것은 단순히 임의의 인공 지능입니다. 여전히 사용 가능한 이동 중 임의로 이동을 선택합니다.


2

파이썬 2.7

이것은 진행중인 작업 제출물로 다른 응답자에게 골격 / 영감을주기 위해 제공합니다. 가능한 모든 우승 라인을 나열한 다음 휴리스틱을 적용하여 해당 라인의 가치에 따라 점수를 매 깁니다. 현재 휴리스틱은 비어 있습니다 (슈퍼 시크릿 작업). 또한 승리 및 충돌 오류 처리를 추가했습니다.

문제에 대한 참고 사항

이기는 선은 몇 개입니까? 1 차원 경우를 고려하십시오. 2 개의 정점, 1 개의 모서리 및 1 개의 선이 있습니다. 2 차원에서는 2 개의 선으로 연결된 4 개의 정점과 2 * n 개의 선으로 연결된 4 개의 모서리가 있습니다. 3 차원에는 4 개의 선으로 연결된 8 개의 정점, 6 * n 개의 선으로 연결된 12 개의 모서리 및 3*n^2선으로 연결된 6 개의면이 있습니다.

일반적으로 정점을 0면, 모서리를 1면 등이라고 부릅니다. 그런 다음 N(i)i면 d의 수, 치수의 수 및 n측면 길이를 나타냅니다. 그런 다음 당첨 횟수는 0.5*sum(N(i)*n^i,i=0..d-1)입니다.

위키 백과 당 N(i)=2^(d-i)*d!/(i!*(n-1)!)이므로 최종 공식은 다음과 같습니다.

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

wolfram | alpha가별로 좋아하지 않는 이것은 매우 빠르게 커지므로 프로그램이 d> 8에 대해 관리 가능한 런타임을 가질 것으로 기대하지 않습니다.

일부 결과 (포맷에 대해 죄송합니다.

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

I / O

현재 입력은 다음과 같이 입력해야합니다 tictactoe.py <ret> n,d <ret> move;move <ret>.-여러 줄을 기록하고 final은 없습니다 ;.

출력은 다음과 같습니다 (x_1,x_2,x_3...).

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() 

편집 : I / O의 경우 논리가 추가되었습니다. 나는 이것이 마크를 할 준비가되었다고 믿는다

이 의견은 처음에는 내가 삭제하고 삭제를 취소 한 자리 표시 자였습니다.


1

파이썬 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)))

대부분의 코드는 Quincunx의 임의 AI 와 동일 합니다. 무작위로 이동을 선택하는 대신, 사전에 사용 가능한 첫 번째 이동을 사전 식으로 선택합니다 (예 : (0,0, ... 0), (0,0, ... 1), (0,0, ... 2) 등).

이것은 매우 쓰레기 전략이지만 거의 항상 무작위로 재생됩니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.