10

好的,这是一个相当复杂的代码高尔夫挑战:实现黑白棋游戏(奥赛罗)。

  • 游戏应该显示游戏板的当前状态,并允许玩家在一台计算机上交替输入动作。
  • 错误的输入和不允许的动作必须被捕获,但可以默默地忽略。
  • 游戏必须在无法进行更多移动时结束(因为棋盘已满或因为没有移动会翻转任何棋子)。
  • 然后比赛必须宣布谁赢了,或者是否是平局。

用尽可能少的字符执行此操作。

会话应如下所示:

 abcdefgh
1        
2        
3        
4   wb   
5   bw   
6        
7        
8        
b>d3
 abcdefgh
1        
2        
3   b    
4   bb   
5   bw   
6        
7        
8        
4

9 回答 9

7

Haskell821 个字符,包括换行符。

import Array
import List
import Maybe
import IO
a=((1,0),(8,7))
z=zip
x=range
y=repeat
o=putStr
i=['a'..'h']
r=[0,1,-1]
d b=' ':i++concatMap(\i->'\n':show(i+1)++map g(take 8$drop(i*8)$elems b))[0..7]++"\n"
e=array a(z(x a)$y 0)//z(x((4,3),(5,4)))[1,-1,-1,1]
f b p i|b!i/=0=Nothing|True=if b==v then Nothing else Just v where v=foldr u b(map(takeWhile(inRange a).($i).iterate.(\(i,j)(k,l)->(i+k,j+l)))$tail[(i,j)|i<-r,j<-r]);u r m=m//case(group$map(m!)r)of([_]:c@(m:_):(l:_):_)|m/=0&&l==p->z(take(1+length c)$r)(y p);_->[]
g=fromJust.(`lookup`z[-1..1]"b w")
h b p=do o$g p:">";hFlush stdout;c:r<-getLine;case f b p(read r,head$elemIndices c i)of;Nothing->h b p;Just m->o(d m)>>case filter(\s->mapMaybe(f m s)(x a)/=[])[-1*p,p]of(n:_)->h m n;_->print$if w==' 'then 'd'else w where w=g$signum$sum$elems m
main=o(d e)>>h e 1

以上内容大致基于此版本:

import Data.Array
import Data.List
import Data.Maybe
import System.IO

type Index = (Int, Int)
type Player = Int -- (-1, 0, 1) for white, unclaimed and black, resp.
type Board = Array Index Player

-- Infix function which add two vectors
(|+|) :: Index -> Index -> Index
(i, j) |+| (k, l) = (i + k, j + l)

-- The functions dim, pieces and board2Str must be updated if one wishes to
-- alter the board's dimensions.

-- Board dimensions
dim :: (Index, Index)
dim = ((0, 0), (7, 7))

-- The pieces that will initially be on the board
pieces :: [(Index, Player)]
pieces = zip (range ((3, 3), (4, 4))) [1, -1, -1, 1]

-- Return a textual representation of the given board
board2Str :: Board -> String
board2Str b = ' ' : ['a'..'h'] ++                               -- column names
  concatMap (\i -> '\n' : show (i + 1) ++                       -- row names
    map player2Str (take 8 $ drop (i * 8) $ elems b)) [0..7] ++ "\n"  -- rows

-- The initial board, including the initial pieces
initial :: Board
initial = array dim (zip (range dim) $ repeat 0) // pieces -- the empty board

-- The directions in which pieces can be flipped.
deltas :: [(Int, Int)]
deltas = tail [(i, j) | i <- [0,1,-1], j <- [0,1,-1]]

-- All 'lines' in any direction starting from the given index
dirs :: Index -> [[Index]]
dirs c = map (takeWhile (inRange dim) . ($ c) . iterate . (|+|)) deltas

-- Attempt to perform a move
move :: Board -> Player -> Index -> Maybe Board
move b p i | b ! i /= 0 = Nothing
           | otherwise  = if b == updateAll then Nothing else Just updateAll
  where
    -- Attempt to swap pieces in all directions
    updateAll = foldr update b (dirs i)
    -- Attempt to swap pieces in the given direction
    update r b' = b' // case (group $ map (b' !) r) of
      ([_]:c@(m:_):(l:_):_) | m /= 0 && l == p ->     -- all conditions are met
        zip (take (1 + length c) $ r) (repeat p)      -- so swap the pieces
      _                                        -> []  -- nothing to swap

player2Str :: Player -> Char
player2Str = fromJust . (`lookup` zip [-1..1] "b w")

-- Test whether the given player can make a move
possible :: Board -> Player -> Bool
possible b p = mapMaybe (move b p) (range dim) /= []

-- Ask the players to make a move in turns, and update the board when required
mainLoop :: Board -> Player -> IO ()
mainLoop b p = do
  putStr $ player2Str p : "> "
  hFlush stdout
  c:r <- getLine  -- get user input (this is very fragile!)
  -- Attempt to perform the suggested move...
  case move b p (read r - 1, head $ elemIndices c ['a'..]) of
    Nothing -> mainLoop b p  -- ...try again if not possible
    Just b' -> do            -- ...accept if possible
      putStr $ board2Str b'  -- print the new board state
      case filter (possible b') [-1 * p, p] of  -- select next player to move
        (p':_) -> mainLoop b' p'   -- move if possible, otherwise game over
        _      -> print $ if winner == ' ' then 'd' else winner
                    where winner = player2Str $ signum $ sum $ elems b'

-- Let the games begin!
main :: IO()
main = putStr (board2Str initial) >> mainLoop initial 1

  :是的,我有 756 个字符,但注意到代码没有正确应用黑白棋的规则。真可惜。

于 2009-10-17T20:14:33.087 回答
4

编辑 2:
更多的调整和技巧,我设法将另外 124 个字符减少到752个字符:

using C=System.Console;class O{static int[]b=new int[100];static int c=1;static void Main(){b[44]=b[55]=-1;b[45]=b[54]=1;var g=true;while(g){C.WriteLine(" abcdefgh");for(int i=10;i<90;i++){switch(i%10){case 0:C.Write(i/10);break;case 9:C.WriteLine();break;default:C.Write("w b"[b[i]+1]);break;}}C.Write("w b"[c+1]+">");var l=C.ReadLine();if(l.Length>1){int x=l[0]-96,y=l[1]-48;if(x>0&x<9&y>0&y<9&&b[y*10+x]<1)c*=f(y*10+x,1);}g=false;for(int y=10;y<90;y+=10)for(int x=y;x<y+8;)g|=b[++x]==0&&f(x,0)<0;}int s=0;foreach(int p in b)s+=p;C.WriteLine(s==0?"d":s<0?"w":"b");}static int f(int ofs,int y){var x=1;foreach(int d in new int[]{-11,-10,-9,-1,1,9,10,11}){int l=1,o=ofs;while(b[o+=d]==-c)l++;if(b[o]==c&l>1){x=-1;while(y>0&l-->0)b[o-=d]=c;}}return x;}}

压缩前:

using Con = System.Console;

class O {

   // Initialise game board, made of ints - 0 is empty, 1 is a black piece, -1 a white.
   // Using a 10x10 board, with the outer ring of empties acting as sentinels.
   static int[] board = new int[100];

   // Color of the current player.
   static int currentColor = 1;

   static void Main() {
     // Set up the four pieces in the middle.
     board[44] = board[55] = -1;
     board[45] = board[54] = 1;
     var legal = true;
     while (legal) {
       // Print game board.
       Con.WriteLine(" abcdefgh");
       for (int i = 10; i < 90; i++) {
         switch (i % 10) {
           case 0: Con.Write(i / 10); break;
           case 9: Con.WriteLine(); break;
           default: Con.Write("w b"[board[i] + 1]); break;
         }
       }
       // Print input, indicating which color's turn it is.
       Con.Write("w b"[currentColor+1] + ">");
       // Parse input.
       var line = Con.ReadLine();
       if (line.Length > 1) {
         int x = line[0] - 96, y = line[1] - 48;
         // Discard malformed input.
         if (x > 0 & x < 9 & y > 0 & y < 9 && board[y * 10 + x] < 1)
           // Check if valid move and if so flip and switch players
           currentColor *= flip(y * 10 + x, 1);
       }
       // See if there are any legal moves by considering all possible ones.
       legal = false;
       for (int y = 10; y < 90; y += 10)
         for (int x = y; x < y + 8;)
           legal |= board[++x] == 0 && flip(x, 0) < 0;
     }
     // Calculate final score: negative is a win for white, positive one for black.
     int score = 0;
     foreach (int piece in board) score += piece;
     Con.WriteLine(score == 0 ? "d" : score < 0 ? "w" : "b");
   }

   // Flip pieces, or explore whether putting down a piece would cause any flips.
   static int flip(int ofs, int commitPutDown) {
     var causesFlips = 1;
     // Explore all straight and diagonal directions from the piece put down.
     foreach (int d in new int[] { -11, -10, -9, -1, 1, 9, 10, 11 }) {
       // Move along that direction - if there is at least one piece of the opposite color next
       // in line, and the pieces of the opposite color are followed by a piece of the same
       // color, do a flip.
       int distance = 1, o = ofs;
       while (board[o += d] == - currentColor) distance++;
       if (board[o] == currentColor & distance > 1) {
         causesFlips = -1;
         while (commitPutDown > 0 & distance-- > 0) board[o -= d] = currentColor;
       }
     }
     return causesFlips;
   }

}

876 个字符的 C# 版本:

using C=System.Console;class O{static void Main(){int[]b=new int[100];b[44]=b[55]=2;b[45]=b[54]=1;int c=1;while(true){C.WriteLine(" abcdefgh");for(int i=10;i<90;i++){switch(i%10){case 0:C.Write(i/10);break;case 9:C.WriteLine();break;default:C.Write(" bw"[b[i]]);break;}}bool g=false;for(int y=10;y<90;y+=10)for(int x=1;x<9;x++){g|=(b[x+y]==0&&f(x+y,b,c,false));}if(!g)break;C.Write(" bw"[c]+">");var l=C.ReadLine();if(l.Length>1){int x=l[0]-96,y=l[1]-48,ofs;if(x>0&x<9&y>0&y<9&&b[ofs=y*10+x]==0)if(f(ofs,b,c,true))b[ofs]=c;c=3-c;}}int s=0;for(int y=10;y<90;y+=10)for(int x=1;x<9;x++)switch(b[y+x]){case 1:s++;break;case 2:s--;break;}C.WriteLine(s==0?"d":s<0?"w":"b");}static bool f(int ofs,int[]b,int p,bool c){var x=false;foreach(int d in new int[]{-11,-10,-9,-1,1,9,10,11}){int l=1,o=ofs;while(b[o+=d]==3-p)l++;if(b[o]==p&l>1){x=true;if(c)while(l-->1)b[o-=d]=p;}}return x;}}

压缩前:

using Con = System.Console;

class Othello {

  static void Main() {
    // Initialise game board, made of ints - 0 is empty, 1 is a black piece, 2 a white.
    // Using a 10x10 board, with the outer ring of empties acting as sentinels.
    int[] board = new int[100];
    // Set up the four pieces in the middle.
    board[44] = board[55] = 2;
    board[45] = board[54] = 1;
    // Color of the current player.
    int currentColor = 1;
    while (true) {
      // Print game board.
      Con.WriteLine(" abcdefgh");
      for (int i = 10; i < 90; i++) {
        switch (i % 10) {
          case 0: Con.Write(i / 10); break;
          case 9: Con.WriteLine(); break;
          default: Con.Write(" bw"[board[i]]); break;
        }
      }
      // See if there are any legal moves by considering all possible ones.
      bool legal = false;
      for (int y = 10; y < 90; y += 10) for (int x = 1; x < 9; x++) {
        legal |= (board[x + y] == 0 && flip(x + y, board, currentColor, false));
      }
      if (!legal) break;
      // Print input, indicating which color's turn it is.
      Con.Write(" bw"[currentColor] + ">");
      // Parse input.
      string l = Con.ReadLine();
      if (l.Length > 1) {
        int x = l[0] - 96, y = l[1] - 48;
        int ofs;
        // Discard malformed input.
        if (x > 0 & x < 9 & y > 0 & y < 9 && board[ofs = y * 10 + x] == 0)
          // Check if valid move & flip if it is - if not, continue.
          if (flip(ofs, board, currentColor, true))
            // Put down the piece itself.
            board[ofs] = currentColor;
        // Switch players.
        currentColor = 3 - currentColor;
      }
    }
    // Calculate final score: negative is a win for white, positive one for black.
    int score = 0;
    for (int y = 10; y < 90; y += 10) for (int x = 1; x < 9; x++)
      switch (board[y + x]) {
        case 1: score++; break;
        case 2: score--; break;
      }
    Con.WriteLine(score == 0 ? "d" : score < 0 ? "w" : "b");
  }

  /** Flip pieces, or explore whether putting down a piece would cause any flips. */
  static bool flip(int ofs, int[] board, int playerColor, bool commitPutDown) {
    bool causesFlips = false;
    // Explore all straight and diagonal directions from the piece put down.
    foreach (int d in new int[] { -11, -10, -9, -1, 1, 9, 10, 11 }) {
      // Move along that direction - if there is at least one piece of the opposite color next
      // in line, and the pieces of the opposite color are followed by a piece of the same
      // color, do a flip.
      int distance = 1, o = ofs;
      while (board[o += d] == 3 - playerColor) distance++;
      if (board[o] == playerColor & distance > 1) {
        causesFlips = true;
        if (commitPutDown) while (distance-- > 1) board[o -= d] = playerColor;
      }
    }
    return causesFlips;
  }

}

我使用 int[100] 而不是 char[10,10] 来简化一些循环和比较。里面有很多小技巧,但除此之外它与原始Java代码基本相同。

编辑:
编辑器显示了一些奇怪的“Col”值,但你应该看看“Ch”值......不是 943 个字符,而是 876......

于 2009-10-17T16:28:45.087 回答
4

C++,672 个字符

这是我的版本。它有 672 个字符,包括换行符:

#include <iostream>
#define F for
#define G F(i p=9;p<90;++p)
#define R return
#define C std::cout
typedef int i;i b[100];i f(i p, i s, i d){i t=0;i q[]={-11,-10,-9,-1,1,9,10,11};F(i o=0;o<8;++o){i c=p+q[o];F(;b[c]==-s;c+=q[o]);if(b[c]==s)F(--t;c!=p;c-=q[o],++t)if(d)b[c]=s;}R t;}i h(i s){G if(!b[p]&&f(p,s,0))R 1;R 0;}i main(){F(i p=0;p<100;++p)b[p]=p<10||p>89||!(p%10%9)?2:0;b[44]=b[55]=-1;b[45]=b[54]=1;i s=1;F(;;){C<<" abcdefgh";G C<<(char)(p%10?"w b\n"[b[p]+1]:'0'+p/10);s=h(s)?s:-s;if(!h(s)){s=-34;G s+=b[p];C<<(s<0?'s':s?'b':'d')<<'\n';R 0;}i p=0;F(;p<9||p>90||b[p]||!f(p,s,1);){C<<"w b"[s+1]<<">";std::string m;std::cin>>m;p=m[0]-'`'+(m[1]-'0')*10;}b[p]=s;s=-s;}}
于 2009-10-20T08:06:07.730 回答
3

Perl,408 个字符

这是 Perl,现在减少到 408 个字符。可以用更简单的方法来宣布获胜者(比如说"B"而不是"Winner: Black\n"),再砍掉 25 个字符。前两个换行符很重要;其他的包括在内是为了便于阅读。

sub O{2&$B[$q+=$_]*$%}sub A{grep{$q=$=;$"=''while&O;$B[$q]*O$q=$=}$B[$=]?():@d}
sub F{$B[$q]=$%;O&&&F}sub D{print'
 ',a..h,$/,(map{($e="@B[$_*9+1..$_*9+8]
")=~y/012/ bw/;$_,$e}1..8),@_}
@d=map{$_,-$_}1,8..10;@B=(@z=(0)x40,$%=2,1,(0)x7,1,2,@z);
for$!(%!){$%^=3;for$=(9..80){$=%9*A&&do{{D$%-2?b:w,"> ";
$_=<>;$==(/./g)[1]*9-96+ord;A||redo}F$q=$=for A;last}}}
$X+=/1/-/2/for@B;D"Winner: ",$X<0?White:$X?Black:None,$/

@B拿着游戏板。$B[$i*9+$j]指行 $i (1..8) 和列 $j (1..8)

@d是 8 个有效方向的列表

O 是一种方便的方法。如果该棋子属于当前玩家的对手,它会增加$q$_当前方向)并返回非零$B[$q]

F 处理在当前方向上翻转的碎片$_

A 检查当前玩家是否可以合法移动$B[$=]并返回可以翻转棋子的方向集

D(@_)画板并打印@_

主循环切换$%(当前玩家)并遍历棋盘上的位置以找到该玩家的合法移动。如果找到任何合法的移动,从标准输入读取移动(重复直到输入有效移动)并更新棋盘。

于 2009-10-19T06:54:25.570 回答
2

我可以用 Java 的 1143 个字符做到这一点:

import java.io.*;public class R{public static void main(String[]args)throws Exception{char[][]b=new char[10][10];for(inty=0;y<10;y++)for(int x=0;x<10;x++)b[y][x]=' ';b[4][4]='w';b[4][5]='b';b[5][4]='b';b[5][5]='w';char c='b';BufferedReader r=new BufferedReader(new InputStreamReader(System.in));while(true){System.out.println(" abcdefgh");boolean m=false;for(int y=1;y<9;y++){System.out.print(y);for(int x=1;x<9;x++){System.out.print(b[y][x]);m=m||(b[y][x]==' '&&f(x,y,b,c,false));}System.out.println();}if(!m)break;System.out.print(c+">");String l = r.readLine();if(l.length()<2)continue;int x=l.charAt(0)-'a'+1;int y=l.charAt(1)-'0';if(x<1||x>8||y<1||y>8||b[y][x]!=' '||!f(x, y, b, c, true))continue;b[y][x]=c;c=c=='b'?'w':'b';}int s=0;for(int y=1;y<9;y++)for(int x=1;x<9;x++)s+=b[y][x]=='b'?1:b[y][x]=='w'?-1:0;System.out.println(s==0?"d":s<0?"w":"b");}static boolean f(int x,int y,char[][]b,char c,boolean o){boolean p=false;for(int u=-1;u<2;u++)for(int v=-1;v<2;v++){if(u==0&&v==0)continue;int d=0;do d++;while(b[y+d*u][x+d*v]==(c=='b'?'w':'b'));if(b[y+d*u][x+d*v]==c&&d>1){p=true;if(o)for(int e=1;e<d;e++)b[y+e*u][x+e*v]=c;}}return p;}}

这是(几乎)相同 Java 的简写版本:

import java.io.*;

public class Reversi {
    public static void main(String[] args) throws Exception {
        // Initialise game board, made of chars - ' ' is empty, 'b' is a black piece, 'w' a white.
        // Using a 10x10 board, with the outer ring of empties acting as sentinels.
        char[][] board = new char[10][10];
        for (int y = 0; y < 10; y++) { for (int x = 0; x < 10; x++) { board[y][x] = ' '; } }
        // Set up the four pieces in the middle.
        board[4][4] = 'w'; board[4][5] = 'b'; board[5][4] = 'b'; board[5][5] = 'w';
        // Color of the current player.
        char currentColor = 'b';
        BufferedReader r = new BufferedReader(new InputStreamReader(System.in));
        while (true) {
            // Print game board.
            System.out.println(" abcdefgh");
            for (int y = 1; y < 9; y++) {
                System.out.print(y);
                for (int x = 1; x < 9; x++) { System.out.print(board[y][x]); }
                System.out.println();
            }
            // See if there are any legal moves by considering all possible ones.
            boolean legalMovesAvailable = false;
            for (int y = 1; y < 9; y++) { for (int x = 1; x < 9; x++) {
                legalMovesAvailable = legalMovesAvailable ||
                        (board[y][x] == ' ' && flip(x, y, board, currentColor, false));
            }}
            if (!legalMovesAvailable) { break; }
            // Print input, indicating which color's turn it is.
            System.out.print(currentColor + ">");
            // Parse input.
            String l = r.readLine();
            if (l.length() < 2) { continue; }
            int x = l.charAt(0) - 'a' + 1;
            int y = l.charAt(1) - '0';
            // Discard malformed input.
            if (x < 1 || x > 8 || y < 1 || y > 8 || board[y][x] != ' ') { continue; }
            // Check if valid move & flip if it is - if not, continue.
            if (!flip(x, y, board, currentColor, true)) { continue; }
            // Put down the piece itself.
            board[y][x] = currentColor;
            // Switch players.
            currentColor = currentColor == 'b' ? 'w' : 'b';
        }
        // Calculate final score: negative is a win for white, positive one for black.
        int score = 0;
        for (int y = 1; y < 9; y++) { for (int x = 1; x < 9; x++) {
            score += board[y][x] == 'b' ? 1 : board[y][x] == 'w' ? -1 : 0;
        }}
        System.out.println(score == 0 ? "d" : score < 0 ? "w" : "b");
    }

    /** Flip pieces, or explore whether putting down a piece would cause any flips. */
    static boolean flip(int pieceX, int pieceY, char[][] board, char playerColor, boolean commitPutDown) {
        boolean causesFlips = false;
        // Explore all straight and diagonal directions from the piece put down.
        for (int dY = -1; dY < 2; dY++) { for (int dX = -1; dX < 2; dX++) {
            if (dY == 0 && dX == 0) { continue; }
            // Move along that direction - if there is at least one piece of the opposite color next
            // in line, and the pieces of the opposite color are followed by a piece of the same
            // color, do a flip.
            int distance = 0;
            do {
                distance++;
            } while (board[pieceY + distance * dY][pieceX + distance * dX] == (playerColor == 'b' ? 'w' : 'b'));
            if (board[pieceY + distance * dY][pieceX + distance * dX] == playerColor && distance > 1) {
                causesFlips = true;
                if (commitPutDown) {
                    for (int distance2 = 1; distance2 < distance; distance2++) {
                        board[pieceY + distance2 * dY][pieceX + distance2 * dX] = playerColor;
                    }
                }
            }
        }}
        return causesFlips;
    }
}
于 2009-10-17T15:35:58.843 回答
2

如前所述,这并不能完全解决问题,但此实现实际上在相当强的水平上播放黑白棋(黑白棋)。在我看来,这是有史以来最好的IOCCC参赛作品之一。您可以在上一届IOCCC 获奖者页面的“lievaart”下找到更多信息。

(我已经复制了已发布的实现,但 GCC 不接受 . 的全部想法#define D define。使用s/D/define/g,程序编译并运行良好。)

#define D define
#D Y return
#D R for
#D e while
#D I printf
#D l int
#D W if
#D C y=v+111;H(x,v)*y++= *x
#D H(a,b)R(a=b+11;a<b+89;a++)
#D s(a)t=scanf("%d",&a)
#D U Z I
#D Z I("123\
45678\n");H(x,V){putchar(".XO"[*x]);W((x-V)%10==8){x+=2;I("%d\n",(x-V)/10-1);}}
l V[1600],u,r[]={-1,-11,-10,-9,1,11,10,9},h[]={11,18,81,88},ih[]={22,27,72,77},
bz,lv=60,*x,*y,m,t;S(d,v,f,_,a,b)l*v;{l c=0,*n=v+100,j=d<u-1?a:-9000,w,z,i,g,q=
3-f;W(d>u){R(w=i=0;i<4;i++)w+=(m=v[h[i]])==f?300:m==q?-300:(t=v[ih[i]])==f?-50:
t==q?50:0;Y w;}H(z,0){W(E(v,z,f,100)){c++;w= -S(d+1,n,q,0,-b,-j);W(w>j){g=bz=z;
j=w;W(w>=b||w>=8003)Y w;}}}W(!c){g=0;W(_){H(x,v)c+= *x==f?1:*x==3-f?-1:0;Y c>0?
8000+c:c-8000;}C;j= -S(d+1,n,q,1,-b,-j);}bz=g;Y d>=u-1?j+(c<<3):j;}main(){R(;t<
1600;t+=100)R(m=0;m<100;m++)V[t+m]=m<11||m>88||(m+1)%10<2?3:0;I("Level:");V[44]
=V[55]=1;V[45]=V[54]=2;s(u);e(lv>0){Z do{I("You:");s(m);}e(!E(V,m,2,0)&&m!=99);
W(m!=99)lv--;W(lv<15&&u<10)u+=2;U("Wait\n");I("Value:%d\n",S(0,V,1,0,-9000,9000
));I("move: %d\n",(lv-=E(V,bz,1,0),bz));}}E(v,z,f,o)l*v;{l*j,q=3-f,g=0,i,w,*k=v
+z;W(*k==0)R(i=7;i>=0;i--){j=k+(w=r[i]);e(*j==q)j+=w;W(*j==f&&j-w!=k){W(!g){g=1
;C;}e(j!=k)*((j-=w)+o)=f;}}Y g;}

您可以在我的Othello页面上找到此版本的现代重新实现。

于 2009-10-18T21:58:59.593 回答
1

假设您的代码在这里工作的优化版本。

1081 个字符

import java.util.*;import java.io.*;class R{public static void main(String[]a)throws Exception{PrintStream h=System.out;char[][]b=new char[10][10];for(int y=0;y<10;y++)for(int x=0;x<10;x++)b[y][x]=' ';b[4][4]='w';b[4][5]='b';b[5][4]='b';b[5][5]='w';char c='b';Scanner r=new Scanner(System.in);while(true){h.println(" abcdefgh");boolean m=false;for(int y=1;y<9;y++){h.print(y);for(int x=1;x<9;x++){h.print(b[y][x]);m=m||(b[y][x]==' '&&f(x,y,b,c,false));}h.println();}if(!m)break;h.print(c+">");String l=r.nextLine();if(l.length()<2)continue;int x=l.charAt(0)-'a'+1;int y=l.charAt(1)-'0';if(x<1||x>8||y<1||y>8||b[y][x]!=' '||!f(x,y,b,c,true))continue;b[y][x]=c;c=c=='b'?'w':'b';}int s=0;for(int y=1;y<9;y++)for(int x=1;x<9;x++)s+=b[y][x]=='b'?1:b[y][x]=='w'?-1:0;h.println(s==0?"d":s<0?"w":"b");}static boolean f(int x,int y,char[][]b,char c,boolean o){boolean p=false;for(int u=-1;u<2;u++)for(int v=-1;v<2;v++){if(u==0&&v==0)continue;int d=0;do d++;while(b[y+d*u][x+d*v]==(c=='b'?'w':'b'));if(b[y+d*u][x+d*v]==c&&d>1){p=true;if(o)for(int e=1;e<d;e++)b[y+e*u][x+e*v]=c;}}return p;}}
于 2009-10-17T15:38:53.450 回答
1

JavaScript/HTML 1419 个字符(输入不完整,已放弃)

Kinopiko 正在放弃此条目。在提交条目后,在处理了这个的非高尔夫版本之后,我意识到问题比看起来要复杂得多。例如,有必要检查不可玩的位置,如果两个玩家都处于不可玩的位置,则宣布获胜。我不知道其他答案是否真的这样做,但逻辑足够复杂,这不再是一个真正有趣的问题。如果其他人想接管并完成此任务,请随时这样做。

这还没有完成(不记分)。我已经让它指向并单击而不是阅读输入。

<html>
<head>
<style>
.s{background-color:green;width:50;height:50;font-size:40}
.w{color:white;font-size:40}
.b{color:black;font-size:40}
.h{width:50;height:50;font-size:30}
</style>
<script>
b=new Array()
for(i=0;i<10;i++)b[i]=new Array(0,0,0,0,0,0,0,0,0);
function j(x,y,c){a=k("s"+x+y)
a.innerHTML=String.fromCharCode(parseInt("25CF",16))
a.className="s "+c}
z="b"
function v(x,y,c){
d=0
for(g=(x>1?x-1:1);g<=(x<8?x+1:8);g++){
for(h=(y>1?y-1:1);h<=(y<8?y+1:8);h++){
if(g==x&&h==y)continue
n=b[g][h]
if(n!=0&&n!=c){e=g-x
f=h-y
for(t=1;;t++){p=x+t*e
q=y+t*f
if(p<1||q<1||p>8||q>8)break
if(!b[p][q])break
if(b[p][q]==c){d=1
for(s=1;s<t;s++){r=x+s*e
u=y+s*f
b[r][u]=c
a=k("s"+r+u)
a.className="s "+c}break}}}}}return d}
function w(x,y){if(b[x][y])return
if(!v(x,y,z))return
b[x][y]=z
j(x,y,z)
z=(z=="b"?"w":"b")}

function create_b(){
b[4][4]=b[5][5]="w";b[4][5]=b[5][4]="b"
t=k("b");
r=o("tr",t)
for(x=0;x<9;x++){
if(x){
h=o("th",r)
h.innerHTML=x}
else 
h=o("th",r)
h.className="h"}
for(y=1;y<9;y++){
r=o("tr",t)
for(x=0;x<9;x++){
if(x){td=o("td",r)
td.className="s a"
td.id="s"+x+y;(function(x,y){td.onclick=function(){w(x,y)}}(x,y))
if(b[x][y])j(x,y,b[x][y])
}else{
h=o("th",r)
h.innerHTML=y
h.className="h"}}}}
function o(p,q){n=document.createElement(p);q.appendChild(n);return n}
function k(i){return document.getElementById(i)}
</script>
</head>
<body onload="create_b()">
<table id="b"></table>
</body>
</html>
于 2009-10-17T19:53:36.983 回答
0

这是一个 1266 字节的 WinXP .COM 文件。这可能看起来有点大,但确实超出了要求。好吧,我有点得意忘形了。

控制:

w,s,a,d = 移动光标
空间=放置一块
进入 = 退出程序

玩起来应该相当直观。

PS源代码在这里!

于 2009-10-24T23:07:25.470 回答