ทำคะแนนในเกมของ Go


23

การให้คะแนนเกมGoเป็นงานที่ไม่ง่ายเกินไป ในอดีตมีการถกเถียงกันหลายเรื่องเกี่ยวกับวิธีการออกแบบกฏเพื่อให้ครอบคลุมกรณีมุมแปลก ๆ ที่อาจเกิดขึ้น โชคดีที่ในภารกิจนี้คุณไม่ต้องทำสิ่งที่ซับซ้อนเช่นชีวิตและความตายหรือการตรวจจับเซกิ ในภารกิจนี้คุณต้องใช้โปรแกรมที่ให้คะแนนเกมตามกฎ Tromp-Taylorโดย Komi
ขั้นตอนการให้คะแนนค่อนข้างง่าย:

จุด P, ไม่ใช่สี C, ถูกพูดถึง C หากมีเส้นทาง (จุดแนวตั้งหรือแนวนอน) จุดสีที่อยู่ติดกันของ P จาก P ไปยังจุดสี C
คะแนนของผู้เล่นคือจำนวนจุดสีของเธอ รวมถึงจำนวนคะแนนที่ว่างที่เข้าถึงได้เฉพาะสีของเธอ

ตัวอย่างเช่นพิจารณากระดานต่อไปนี้ X, Oและ-แสดงว่าสีดำ, สีขาวและทาสีทางแยก:

- - - X - O - - -
- - - X - O - - -
- - - X - O - - -
- - - X O - - O -
X X X O - O O - -
- - - X O - - O O
- - - X - O - - -
- - - X - O - X -
- - - - - O - - -

การใช้กฎการให้คะแนนจะให้ผลลัพธ์ต่อไปนี้ x, oและ-เป็นตัวแทนของทางแยกทาสีที่จะถูกนับเป็นสีดำสีขาวและจุดที่ไม่มีใคร

x x x X - O o o o
x x x X - O o o o
x x x X - O o o o
x x x X O o o O o
X X X O o O O o o
- - - X O - - O O
- - - X - O - - -
- - - X - O - X -
- - - - - O - - -

ตามแผนภาพสีดำมี 23 จุดสีขาวมีอาณาเขต 29 จุด ดังนั้นโปรแกรมของคุณควรพิมพ์W+6สำหรับบอร์ดนี้

ฉันหวังว่ามันจะชัดเจนพอด้วยวิธีนี้

อินพุตและเอาต์พุต

การป้อนข้อมูลที่เป็นสตริงที่ประกอบด้วยตรงของตัวละครX, O, -ที่nไม่เป็นที่รู้จักที่รวบรวมเวลา โปรแกรมของคุณควรละเว้นอักขระอื่น ๆ ทั้งหมดในสตรีมอินพุต พฤติกรรมจะไม่ได้กำหนดถ้าไม่มีจำนวนเต็มnดังกล่าวว่าจำนวนXO-ตัวอักษรเท่ากับn² คุณอาจจะคิดว่าnอยู่ใน[0 255]

ลำดับของอักขระจะถูกตีความเป็นแบบ Go-board ของnแถวและคอลัมน์ เอาท์พุทเป็นค่าสัมบูรณ์ของความแตกต่างของจำนวนคะแนนทั้งหมดของสีขาวและสีดำเป็นตัวแทนทศนิยม ถ้าสีขาวมีแต้มมากกว่าจะนำหน้าด้วยW+ถ้าสีดำมีแต้มมากกว่านั้นก็จะขึ้นB+ต้นด้วย Jigoในกรณีที่ผู้เล่นทั้งสองมีจำนวนเท่ากับของจุดออกเป็น

อินพุตจะถูกอ่านในลักษณะการใช้งานที่กำหนดไว้ อินพุตอาจไม่ได้เป็นส่วนหนึ่งของซอร์สโค้ด

เงื่อนไขการชนะ

นี่คือรหัสกอล์ฟ ใช้รหัสการประชุมกอล์ฟตามปกติ การส่งที่มีจำนวนอักขระน้อยที่สุดในแหล่งที่มาจะชนะ เฉพาะโปรแกรมที่ปฏิบัติตามข้อกำหนดอย่างสมบูรณ์เท่านั้นที่จะชนะ

กรณีทดสอบ

การป้อนข้อมูล:

- - - X - O - - -
- - - X - O - - -
- - - X - O - - -
- - - X O - - O -
X X X O - O O - -
- - - X O - - O O
- - - X - O - - -
- - - X - O - X -
- - - - - O - - -

เอาท์พุท: W+6

การป้อนข้อมูล:

Xavier is insane -- says Oliver

เอาท์พุท: Jigo

Inpout:

Code-Golf

เอาท์พุท: Jigo

การป้อนข้อมูล:

-XXXXXXX-XOOOOOOOXXO-OXXXOXXXOX--XOXXOOX
-
XOOXXOX--XOXXXOXXXO-OXXOOOOOOOX-XXXXXXX-

เอาท์พุท: B+21

การป้อนข้อมูล:

- - X O O O O X X - - - - - - X O O -
- X X O X O X X O X X X X X X - X O -
- X O O X X X - O O O X O O X X X O -
- X O O O X X O O O O O O X X X O - -
- - X X O X - X X X X O O O O O O O -
- - X O O X X X - X X X O O O X X O -
- - X O - O X O X O O O O O X X X O -
- X O O - O O O X X X X X O O X O - -
- X X X O - - - O X O X X X O X O - -
X O O O O - - O - O O O O X X X O O -
X X O - - - O - - O O X X - - X X O O
X O O O - - O - O O X - - - - X O O X
- X X X O O X O O X X - - - - X X X X
X - X X X O X X O O X - - X X O X O O
X X O O X O X O X X - - - X O O O O -
X O - O X X X O X - - - - - X O - - -
O O - O X O O O O X X - X X X X O - -
O O - O O O X O X X - - X - X X O - -
- - O - - O X X X - - - - X O O O - -

เอาท์พุท: B+6

การทดสอบเพิ่มเติมจะมาในเร็ว ๆ นี้

การดำเนินการอ้างอิง

ฉันสร้างการใช้งานอ้างอิงที่เขียนใน ANSI C การใช้งานนี้จะอ่านอินพุตจากอินพุตมาตรฐานและเขียนเอาต์พุตไปยังเอาต์พุตมาตรฐาน

/* http://codegolf.stackexchange.com/q/6693/134
 * reference implementation
 * by user FUZxxl
 */

#include <stdio.h>
#include <stdlib.h>

#define MAXBOARD 256

/* bit 0x01: black colour
 * bit 0x02: white colour
 * bit 0x04: there is a stone on the intersection
 */

enum colour {
    UNCOLOURED    = 0x0,
    BLACK_REACHED = 0x1,
    WHITE_REACHED = 0x2,
    BOTH_REACHED  = 0x3,
    HAS_STONE     = 0x4,
    BLACK         = 0x5,
    WHITE         = 0x6
};

static enum colour board[MAXBOARD * MAXBOARD] = { 0 };

static int bsize = 0;

static void read_input(void);
static void fill_board(void);
static void show_score(void);

int main()
{
    read_input();
    fill_board();
    show_score();
    return EXIT_SUCCESS;
}

static void read_input(void)
{
    int n = 0;
    int invalue;

    while ((invalue = getchar()) != EOF) {
        switch (invalue) {
            case '-': board[n++] = UNCOLOURED; break;
            case 'X': board[n++] = BLACK; break;
            case 'O': board[n++] = WHITE; break;
        }
    }

    while (bsize * bsize < n) bsize++;

    /* your program may exhibit undefined behaviour if this is true */
    if (bsize * bsize != n) exit(EXIT_FAILURE);
}

static void fill_board(void)
{
    int i,j;
    int changes;
    enum colour here, top, bottom, left, right, accum;

    do {
        changes = 0;

        for (i = 0; i < bsize; ++i) {
            for (j = 0; j < bsize; ++j) {

                here   = board[i * bsize + j];
                if (here >= BOTH_REACHED) continue;

                top    = i == 0 ? UNCOLOURED : board[(i - 1) * bsize + j];
                left   = j == 0 ? UNCOLOURED : board[i * bsize + j - 1];
                bottom = i == bsize-1 ? UNCOLOURED : board[(i + 1) * bsize + j];
                right  = j == bsize-1 ? UNCOLOURED : board[i * bsize + j + 1];

                accum = here | top | bottom | left | right;
                accum &= ~HAS_STONE;

                changes |= board[i * bsize + j] != accum;

                board[i * bsize + j] = accum;

            }
        }

    } while (changes);
}

static void show_score(void) {
    int w = 0, b = 0, n;

    for (n = 0; n < bsize*bsize; ++n) switch (board[n] & ~HAS_STONE) {
        case BLACK_REACHED: ++b; break;
        case WHITE_REACHED: ++w; break;
    }

    if (b != w)
        printf("%s%i\n",b>w?"B+":"W+",abs(b-w));
    else
        printf("Jigo\n");
}

สมมุติว่าคุณหมายถึงผลลัพธ์สุดท้ายเป็นW+7อย่างไร
dmckee

ไม่ ... คุณมาถึงข้อสรุปนี้ได้อย่างไร
FUZxxl

เอ่อ ... ผมสันนิษฐานว่าS+เป็นพิมพ์ผิด (เพราะคุณระบุไว้ก่อนหน้าการส่งออกไปได้เป็นอย่างใดอย่างหนึ่งW+, B+หรือJigo) และฉันมองไปที่แป้นพิมพ์ของฉันและเห็นSอยู่ใกล้W... หรือคุณจะใช้ Dvorak?
dmckee

@dmckee ฉันคิดว่า "S" มาจากภาษาเยอรมัน "Schwarz" แทนที่จะเป็น "Black"
Howard

โอ้ ... คุณพูดถูก ขออภัยด้วย
FUZxxl

คำตอบ:


2

GolfScript (105 ไบต์)

{'-XO'?}/]-1-.{2*3%}%{.,:N),{.*N=}?/{{[{.2$+1={+.}*}*]}%zip}N*[]*.1--,\}2*-.{.0>'W+B+'2/=\abs}{;'Jigo'}if

สาธิตออนไลน์

น้ำท่วมเติมดัดแปลงมาจากคำตอบก่อนหน้านี้ของฉัน

วิธีแก้ปัญหาน้ำท่วมเติมสำเนาต้นฉบับของบอร์ดหนึ่งชุดด้วย X และอีกชุดหนึ่งมี O. ดังนั้นเซลล์ที่ว่างซึ่งสามารถเข้าถึงได้โดยทั้งสองสีจะได้รับคะแนนสำหรับทั้งสอง แต่ยกเลิกในการลบ


ยุติธรรมพอสมควร คุณอาจชนะรอบนี้
FUZxxl

6

C ( 438 434 413 382 364 336 322 298 294 292 290 ตัวอักษร)

#define I b[d*g+e
a;b[65536];c;d;e;f;g;main(){for(;d=getchar()+1;f++)b[f]=d-80?d-89?d-46&&
f--:5:6,g+=g*g<f;while(!c--)for(d=g;d--;)for(e=g;e--;)I]<3?a=3&(I]|!!d*I
-g]|!!e*I-1]|(d<g-1)*I+g]|(e<g-1)*I+1]),c&=I]==a,I]=a:0;while(f--)c+=b[f
]%2-b[f]/2%2;printf(c?"%c+%i":"Jigo",c>0?66:87,abs(c));}

ขึ้นบรรทัดใหม่ทั้งหมดยกเว้นบรรทัดแรกที่แทรกเพื่อความชัดเจนยิ่งขึ้น รุ่นความเห็นและอ่านได้ชัดเจนมากขึ้นเล็กน้อยสามารถพบได้ที่นี่

คำตอบนี้เป็นวิธีการแก้ปัญหาอ้างอิง แต่กับสิ่งที่ไร้ประโยชน์ทั้งหมด (เช่นประเภท [ใครต้องการอะไรที่แตกต่างจากintอยู่แล้ว?]) และการปฏิบัติตามมาตรฐาน [คืนค่าหลัก? โปรด!]

การแก้ไขและปรับปรุง

438 → 434

ลดการกำหนดค่าเริ่มต้นอย่างชัดเจนของตัวแปรหลังจากที่ฉันมั่นใจในตัวเองว่าพวกเขาจะเริ่มต้นโดยอัตโนมัติ0ตามมาตรฐาน

434 → 413

คำสั่งกรณีที่ถูกลบ: หากจุดตัดที่ไม่มีสีสามารถเข้าถึงได้จากทั้งขาวดำเราสามารถนับเป็นจุดเดียวสำหรับทั้งสองเพื่อทำให้โปรแกรมง่ายขึ้น สลับสาขาตรรกะเพื่อหลีกเลี่ยงการปฏิเสธ

413 → 382

กำหนดdให้getchar()+1เพื่อบันทึกวงเล็บหนึ่งคู่ ภายใต้สมมติฐานที่bถูกเตรียมใช้งานเป็นศูนย์ให้เรียงลำดับcaseคำสั่งใหม่โดยยกเลิกbreakคำสั่งทั้งหมด มีความยาวมากกว่า(a>b?c:0) มีความยาวมากกว่า(a>b)*c(d+1)*g+ed*g+e+g

382 → 364

ปรับปรุงการวนซ้ำไม่มีการขึ้นบรรทัดใหม่ในเอาต์พุตรูทีนเอาต์พุตสั้นลง

364 → 336

กำจัดswitchข้อความนั้น (ขอบคุณฮาวเวิร์ด!) ติดตามความแตกต่างของคะแนนสำหรับตัวละครทั้งสอง ปฏิเสธcหนึ่งตัวอักษร สี่ตัวละครในใหญ่หรือประโยค

336 → 323

แทนที่&ด้วยการ%อนุญาตให้ลบวงเล็บสำหรับสี่อักขระ หลอมสแควร์รูทเข้ากับวนรอบอินพุตสำหรับอักขระเก้าตัวหรือมากกว่านั้น (ใช่!) แล้วนำออกifหนึ่งอักขระ

323 → 298

แนะนำแมโครHเพื่อแทนที่มักจะเกิดขึ้นและขนาดใหญ่b[d*g+e]สร้าง

298 → 294

เปลี่ยนa&=~4ไปเป็นเราทุกสังเกตต่ำสุดสามไบต์a&=3 aยังมีการเปลี่ยนแปลงให้กับร่างกายห่วงจาก((a=I])<3)?a|=...ไปI]<3?a=I]|...ซึ่งเป็นตัวละครสองตัวที่สั้นกว่า นอกจากนี้แนะนำhแทนการใช้ซ้ำcซึ่งมีความยาวหนึ่งตัวอักษร

294 → 292

กำจัดhตัวแปร ถ้าเราทดสอบcกับ!c--แทน!c++, cเท่ากับ 0 ในตอนท้ายของห่วงน้ำท่วมเติมและสามารถจึงถูกนำมาใช้เพื่อวัตถุประสงค์hที่ถูกใช้มาก่อน (เช่นคะแนนการรักษา)

292 → 290

แทนที่สร้างd-46?f--:0ด้วยd-46&&f--ซึ่งเป็นที่สั้นลงโดยตัวอักษรและรวมทั้งสองที่ได้รับมอบหมายไปaในวงภายใน


1
คุณสามารถแทนที่คำสั่งสวิตช์ด้วยสิ่งที่ต้องการ{b[f]=d-80?d-89?d-46?f--:0:5:6;f++;}บันทึกอักขระหลายตัว
โฮเวิร์ด

@Howard: ใช่ มันใช้งานได้ดีจริงๆ! ขอบคุณ
FUZxxl

"เพื่อความชัดเจนที่เพิ่มขึ้น" - ราวกับว่า
tomsmeding

@ tomsmeding การเลื่อนหนึ่งบรรทัดนั้นอ่านง่ายกว่ามาก นอกจากนี้ยังมีการเชื่อมโยงเวอร์ชันที่มีความคิดเห็นด้วย
FUZxxl

@FUZxxl นั่นหมายถึงการล้อเล่น :) นอกจากนี้คุณพูดถูกว่าดีกว่าใน 1 บรรทัด
tomsmeding

6

J ( 140 136 131 129 119 117ตัวอักษร)

หลังจากเพิ่มทักษะ J ของฉันในที่สุดฉันก็สามารถยื่นข้อเสนอใน J ได้ แต่มันก็ค่อนข้างนาน

exit echo>(*{'Jigo';('B+',":);'W+',":@|)+/,-/1 2=/(]OR(0=[)*[:OR((,.|.)0,i:1)|.!.0])^:_~($~,~@%:@#)3-.~'-XO'i:1!:1]3

อัลกอริทึมที่นำมาใช้โดยการส่งนี้จะคล้ายกันมากกับการดำเนินการอ้างอิง แต่แตกต่างกันในวิธีการจัดการเขตข้อมูลที่ถูกครอบครอง

นี่คือวิธีการแก้ปัญหาแบ่งออกเป็นส่วนอื่น ๆ เพื่อให้เข้าใจง่ายขึ้น ทางออกของสนามกอล์ฟนั้นแตกต่างจากนี้เล็กน้อย แต่ความแตกต่างนั้นไม่ใหญ่มาก

input =. 3 -.~ '-XO' i: 1!:1 ] 3
board =. ($~ ,~@%:@#) input
NB. shift up, down, left, right
rotm =. (,. |.) 0 , i: 1
fill =. ] OR (0 = [) * [: OR rotm |.!.0 ]
filledboard =. fill^:_~ board
score =. +/ , -/ 1 2 =/ filledboard
echo > (* { 'Jigo' ; ('B+' , ":) ; ('W+', ":@|)) score
exit 0

5

GolfScript 190 ตัวอักษร

{"XO-"?)},:v,.),\{\.*=}+,~:s.*:`0\,{s%!\2*+}/:r;88{0v@{=\2*+}+/}:%~79%1${{:<.r|r^2*|<2/r|r^|<2s?:h/|<h*|1$|1$^2`?(&}`*}:a~@@a\;.2$|2${^2*)2base{+}*}:m~@2$|@m-.{"BW"1/1$0>="+"@abs}{;"Jigo"}if

สคริปต์ยาวกว่าที่ฉันคิดไว้มากในตอนแรก ส่งผ่านอินพุตใด ๆ บน STDIN และเอาต์พุตจะถูกพิมพ์เมื่อโปรแกรมหยุดทำงาน


2

ทับทิม (314)

อาจทำให้สั้นลงด้วยเวลามากขึ้น:

q={?-=>0,?X=>5,?O=>6};b=[];$<.chars{|c|(t=q[c])&&b<<t}
z=Math.sqrt b.size
loop{c=b.each_with_index.map{|h,i|
next h if h>2
x=i%z
y=i/z
u=y<1?0:b[i-z]
l=x<1?0:b[i-1]
d=y>z-2?0:b[i+z]
r=x>z-2?0:b[i+1]
~4&(h|u|d|l|r)}
break if c==b
b=c}
b.map!{|h|h&~4}
s=b.count(1)-b.count(2)
puts s==0?"Jigo":s>0?"B+#{s}":"W+#{-s}"
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.