Tic-Tac-Toe và Chess, với ít nhân vật [khác biệt]


9

Trong hình thức này của trò chơi Tic-Tac-Chec, mục tiêu là di chuyển các quân cờ để có được bốn liên tiếp. Mục tiêu của bạn ở đây là tìm hiểu xem một vị trí có bước đi chiến thắng hay không.

Quy tắc

Các quy tắc tương tự, nhưng không giống với quy tắc của Tic-Tac-Chec.

Bảng có 4 ô vuông. Mỗi người chơi có một tân binh, giám mục, hiệp sĩ và nữ hoàng. Đến lượt bạn, bạn có hai lựa chọn. Bạn có thể di chuyển một trong những quân cờ của mình trên bàn cờ, tuân theo các quy tắc cờ tiêu chuẩn. Hoặc bạn có thể đặt một mảnh chưa có trên bảng, trên bất kỳ nơi nào không có người.

Nếu bạn di chuyển một mảnh hiện có lên mảnh của đối thủ, mảnh của chúng sẽ được lấy ra khỏi bảng và trả lại cho chúng. Tuy nhiên, bạn không được đặt một mảnh mới lên trên mảnh của đối thủ.

Ngay khi một người chơi có tất cả các quân cờ của họ trong một hàng (hoặc cột hoặc đường chéo), họ sẽ thắng.

Thử thách

Viết một chương trình đầy đủ chấp nhận một bảng từ STDIN và đưa ra liệu người chơi trắng có thể giành chiến thắng trong lượt tiếp theo hay không.

Đầu vào

Bốn chuỗi gồm 4 ký tự mỗi. Mỗi nhân vật là một không gian hoặc một quân cờ. Chỉ các tân binh, giám mục, hiệp sĩ và nữ hoàng được sử dụng, và nhiều nhất một trong mỗi (mỗi màu) có thể xuất hiện. Cả hai người chơi đều không có bốn liên tiếp.

Bạn có thể chọn chấp nhận làm đầu vào biểu tượng Unicode cho các quân cờ hoặc chữ cái. Nếu bạn chọn chữ cái, RBKQđại diện cho các mảnh màu trắng và rbkqđại diện cho các mảnh màu đen.

Đầu ra

Nếu người chơi trắng có thể giành chiến thắng ở lượt tiếp theo, hãy xuất truehoặc 1. Nếu không, đầu ra falsehoặc 0.

Chương trình

Chọn một số X. Chương trình của bạn có thể chứa tối đa X ký tự riêng biệt và không có ký tự nào có thể xuất hiện nhiều hơn X lần.

Chiến thắng

X thấp nhất thắng. Trong trường hợp hòa, ít nhân vật nhất sẽ thắng.

Ví dụ

Những ví dụ này giả sử đầu vào sử dụng các chữ cái để thể hiện các mảnh.

rkb 


RB Q
true - the white player can place the knight to complete the bottom row.
-----------------------------------
rk    


RBbQ
false - the black bishop prevents the white knight from completing the row.
-----------------------------------
rk  
 K  

RBbQ
true - the white knight can capture the black bishop and complete the row.
-----------------------------------
rkRB

 Qb 
K   
true - the white rook can move down one to complete the diagonal.

Vì vậy, mã oOo sẽ giành chiến thắng?
kennytm

@KennyTM Không có char nào có thể xuất hiện nhiều hơn X lần sẽ khiến oOo trở nên vô dụng
Trình tối ưu hóa

@Optimizer OK xin lỗi đọc sai quy tắc.
kennytm

2
Các ví dụ có thể được đưa vào một định dạng dễ đọc hơn không, rất khó để xem vị trí của các mảnh là gì và chúng thuộc màu nào.
Tally

Là khoảng trắng được phép?

Câu trả lời:


3

C, 53 ký tự riêng biệt

Điều này sử dụng "#%&()*+,-./01234569;<=>BKQR[\]acdefghilmnoprstu{|}, không gian và dòng mới, được phân phối như sau: 24 × \n, 33 × , 20 × ", 2 × #, 3 × %, 16 × &, 46 × (, 46 × ), 13 × *, 12 × +, 35 × ,, 10 × -, 2 × ., 2 × /, 18 × 0, 9 × 1, 4 × 2, 4 × 3, 4 × 4, 4 × 5, 3 × 6, 3 × 9, 34 × ;, 6 × <, 46 × =, 2 × >, 2 × B, 2 × K, 3 × Q, 2 × R, 8 × [, 1 × \, 8 × ], 39 × a, 23 × c, 5 × d, 19 × e, 15 × f, 1 × g, 22 × h, 36 × i, 5 × l, 1 × m, 35 × n, 9 ×o, 33 × p, 44 × r, 20 × s, 43 × t, 15 × u, 8 × {, 14 × |, 8 × }.

#include <stdio.h>
#include <string.h>
int n(char*a,char*e,int i)
{int c=0;for(;a<e;)c+=*a++=="\n"[0];return c==i;}

int p(char *t, int r, int u)
{char h[]=" RBQK";char*p=t+r;char*a;int c=0;
for(int i=0;i<=3;++i,p+=u){char*s=strchr(h,*p);if(s&&s==h==0){++c;*s=" "[0];}else{a=p;}}
if(c-3)return 0;
char o=h[strspn(h, " ")];
p=strchr(t, o);
if(p==0)return*a==" "[0];
if(p<a){char*s=p;p=a;a=s;}
if(o=="K"[0])return(p-a)==3&&n(a,p,1)||(p-a)==2+5&&n(a,p,1)||(p-a)==9&&n(a,p,2)||(p-a)==11&&n(a,p,2);
if((p-a)%5==0||n(a,p,0))return (int)strchr("RQ", o);
return((p-a)%4==0&&n(a,p,(p-a)/4)||(p-a)%6==0&&n(a,p,(p-a)/6))&&strchr("BQ",o);}

int f(char *t)
{for(int i=0;i<4;++i)if(p(t,i,5)||p(t,i*5,1))return 1;
return p(t,0,6)||p(t,3,4);}

int main()
{char t[20];fread(t,19,1,stdin);t[19]=0;
if(f(t))puts("true");else puts("false");}

Giải trình

#include <stdio.h>
#include <string.h>

/* count newlines */    
int n(char *a, char *e)
{
    int c = 0;
    for (;a<e;) c += *a++=='\n';
    return c;
}

/* check a single row, column or diagonal */
int p(char *t, int start, int stride)
{
    char h[] = " RBQK"; /* pieces not in line */
    char *p = t+start;
    char *a;
    int c = 0;
    for (int i = 0;  i <= 3;  ++i, p+=stride) {
        char *s = strchr(h, *p);
        if (s && s == h == 0) {
            /* a white piece */
            ++c;
            *s = " "[0];
        } else {
            /* candidate target square */
            a = p;
        }
    }

    /* did we find three white pieces in this line? */
    if (c != 3)
        return 0;

    char o = h[strspn(h, " ")];

    p = strchr(t, o);

    if (p==0)
        return *a == " "[0];

    /* ensure a < p */
    if (p < a) {
        char *s = p;
        p = a;
        a = s;
    }

    /* knight moves */
    if (o == 'K')
        return (p-a)==3 && n(a,p)==1
            || (p-a)==7 && n(a,p)==1
            || (p-a)==9 && n(a,p)==2
            || (p-a)==11 && n(a,p)==2;

    /* rook moves */
    if ((p-a)%5 == 0 || n(a,p)==0)
        return 0==strchr("RQ", o)==0;

    /* bishop moves */
    return
        ((p-a)%4==0 && n(a,p)==(p-a)/4 ||
         (p-a)%6==0 && n(a,p)==(p-a)/6)
        && strchr("BQ", o);
}

/* main predicate function */
int f(char *t)
{
    /* try rows and columns */
    for (int i = 0;  i < 4;  ++i)
        if (p(t, i, 5) || p(t, i*5, 1))
            return 1;
    /* try diagonals */
    return p(t, 0, 6) || p(t, 3, 4);
}

int main()
{
    char t[20];
    fread(t, 19, 1, stdin);
    t[19]=0;
    if (f(t)) puts("true"); else puts("false");
}

Nó hoạt động bằng cách tìm kiếm một hàng, cột hoặc đường chéo chứa ba trong số các mảnh màu trắng; achỉ vào vị trí mục tiêu (chưa chứa một mảnh màu trắng). Sau đó, phần còn thiếu ( o) được xác định - đó là phần chúng tôi đã không xóa khỏi chuỗi hnhư chúng tôi đã thấy.

Nếu tác phẩm không nằm trên bảng, nó phải nằm trong tay và nó chỉ có thể được chơi trong một không gian. Mặt khác (nếu chúng ta tìm thấy nó trên bảng), nó phải ở vị trí có thể di chuyển vào ô vuông mục tiêu. Vì di chuyển là đảo ngược, chúng tôi trao đổi nếu cần thiết, do đó a < p.

Chúng tôi kiểm tra di chuyển hiệp sĩ trước - có bốn động thái đi xuống hợp pháp và chúng tôi tránh quấn quanh các cạnh trái / phải của bảng bằng cách xác minh số lượng dòng mới chúng tôi vượt qua.

Sau đó, chúng tôi kiểm tra các động tác rook, và sau đó giám mục di chuyển, sử dụng một thuật toán tương tự (và một nữ hoàng có thể sử dụng một trong hai động tác này).

Chương trình kiểm tra

int expect_true(char *board)
{
    if (strlen(board) != 19) {
        fprintf(stderr, "Wrong length board:\n%s\n\n", board);
        return 1;
    }
    if (!f(board)) {
        fprintf(stderr, "Expected true, but got false, for\n%s\n\n", board);
        return 1;
    }
    return 0;
}

int expect_false(char *board)
{
    if (strlen(board) != 19) {
        fprintf(stderr, "Wrong length board:\n%s\n\n", board);
        return 1;
    }
    if (f(board)) {
        fprintf(stderr, "Expected false, but got true, for\n%s\n\n", board);
        return 1;
    }
    return 0;
}


int main()
{
    return
        + expect_true("rkb \n"
                      "    \n"
                      "    \n"
                      "RB Q")
        + expect_false("rk  \n"
                       "    \n"
                       "    \n"
                       "RBbQ")
        + expect_true("rk  \n"
                      " K  \n"
                      "    \n"
                      "RBbQ")
        + expect_true("rk  \n"
                      "    \n"
                      "K   \n"
                      "RBbQ")
        + expect_true("rkRB\n"
                       "    \n"
                       " Qb \n"
                       "K   ")
        + expect_true("rk  \n"
                      "    \n"
                      "K   \n"
                      "RBbQ");
}

Chương trình đếm (trong C ++)

#include<algorithm>
#include<iostream>
#include<map>

int main()
{
    std::map<char,int> m;
    for (int c;  (c = getchar()) != EOF; )
        ++m[c];

    for (auto e: m)
        std::cout << e.first;

    std::cout << "\n distributed as follows: ";
    for (auto e: m)
        std::cout << e.second << "×`" << e.first << "`, ";
}

1
Gợi ý 6+3cho 916+3cho19
trầ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.