亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? ics 180, april 8, 1997.htm

?? 介紹各種經典算法的代碼。說明詳細
?? HTM
字號:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<!-- saved from url=(0049)http://www.ics.uci.edu/~eppstein/180a/970408.html -->
<HTML><HEAD><TITLE>ICS 180, April 8, 1997</TITLE>
<META content="text/html; charset=gb2312" http-equiv=Content-Type>
<META name=Owner value="eppstein">
<META name=Reply-To value="eppstein@ics.uci.edu">
<META content="MSHTML 5.00.2614.3500" name=GENERATOR></HEAD>
<BODY><IMG alt="" height=72 src="ICS 180, April 8, 1997.files/icslogo2.gif" 
width=472>
<P><A href="http://www.ics.uci.edu/~eppstein/180a/index.html">
<H1>ICS 180A, Spring 1997:<BR>Strategy and board game programming</H1></A>
<H2>Lecture notes for April 8, 1997<BR>Board representations</H2>In order to 
operate, any game program needs to be able to store and manipulate two kinds of 
objects: game positions, and game moves. These representations need to allow the 
program to perform the following operations: 
<UL>
  <LI>Make a given move (not just when user requests, but as part of search) 
  <LI>Undo a move (not just for user interface, needed in search) 
  <LI>Display board to user 
  <LI>Generate a list of all possible moves 
  <LI>Evaluate a board position </LI></UL>Everything except displaying the board 
must be fast since it happens in the inner loops of the search routine. (Board 
display can be slower since it doesn't happen often.) 
<P>The internal representation of moves should be very concise (since we don't 
want to spend too much time generating long lists of moves) and quickly 
decodable. But (very important) it should also able to represent all possible 
moves! E.g. for chess, a typical computer move representation is to store the 
starting square and ending square of the piece being moved; for instance the 
common beginning move of the king's pawn forward two squares would be 
represented "e2e4" where e2 is the name for the initial position of the pawn and 
e4 is the name for its final position. The piece being captured (if any) does 
not need to be stored as part of the move since it is determined by the final 
position. In the computer, these positions can be represented as 6-bit values, 
so the whole move could be stored internally as two bytes. But (even though some 
programs are based on it) this representation is not quite capable of 
representing all moves! In castling, two pieces move, a king and a rook, but we 
can handle this as a special case in which we list only the king movement. More 
importantly, if a pawn moves from the seventh rank to the eighth, it can be 
replaced by any of four pieces: queen, rook, knight, and bishop. The 
representation above doesn't allow us to specify which replacement is happening. 
So when designing a move representation, one should be careful to make sure that 
it covers all the special cases that might happen in your game. 
<P>The onternal representation of board can be less concise but should still not 
be too huge. It must represent all relevant information, not just all visible 
information, but not including irrelevant information. E.g. in chess, we need to 
know the positions of pieces on the board (the obvious visible information), but 
we also need to know some invisible information: who's on move, whether either 
player can castle, whether an en passant capture is possible, and how many moves 
it's been since the last capture or pawn move. We also need to know something 
about what positions have occurred in the past (because of triple repetition) 
but don't need to know the entire list of past moves. 
<H3>Example of Multiple Representation Possibilities: Chess</H3>There are many 
possible ways of representing even something with as clearly defined a structure 
as a chessboard in a computer. Here are some of the methods that have been used 
by chess programs. 
<P><B>Representation 1: 8x8 array of squares</B>. Within each square, keep a 
value indicating which piece is present in the square (e.g. enum { empty, wK, 
wN, wB, wR, wQ, wP, bK, bN, bR, bQ, bP }). Advantages: (1) simple. (2) easy to 
compute material scores: <PRE>    for  (i=0;i&lt;8;i++)
        for(j=0;j&lt;8;j++)
            score += value[square[i,j]];
</PRE>It's a little messy but not really hard to compute possible moves; you can 
loop through the squares finding pieces of appropriate color and branch 
according to piece type: <PRE>    for  (i=0;i&lt;8;i++)
        for(j=0;j&lt;8;j++)
            switch (board[i,j]) {
            case wP:
                if (board[i+1,j] empty) generate move to (i+1,j)
                if (i==2 &amp;&amp; board[i+1,j] empty &amp;&amp; board[i+2,j] empty)
                    generate move to (i+2,j)
                if (j &gt; 0 &amp;&amp; board[i+1,j-1] contains black piece)
                    generate capture of (i+1,j-1)
                if (j &lt; 7 &amp;&amp; board[i+1,j+1] contains black piece)
                    generate capture of (i+1,j+1)
                break;
            ...
            }
</PRE>however there are various annoying boundary conditions to check (e.g. a 
pawn on rook-file shouldn't try to capture to one side) making this code 
complicated and slower than necessary. 
<P><B>Representation 2: extended array</B>. 10x10, containing extra boundary 
squares containing a special "boundary" value added to the enum. This simpifies 
some of the cases (reduces number of conditions in the if-statements above) at 
the expense of a little space. 
<P><B>Representation 3: 0x88</B>. The name of this representation comes from a 
trick for testing whether a square is a valid move involving the binary 
representation of the number 136 (which in hexadecimal is 0x88). We give each 
square of the board a number (a single byte), of which the high 4 bits are the 
row and the low 4 bits are the column: <PRE>    112 113 114 115 116 117 118 119
    96  97  98  99  100 101 102 103
    80  81  82  83  84  85  86  87
    64  65  66  67  68  69  70  71
    48  49  50  51  52  53  54  55
    32  33  34  35  36  37  38  39
    16  17  18  19  20  21  22  23
    0   1   2   3   4   5   6   7
</PRE>Then the square left of i is i-1, right is i+1, up is i+16, down is i-16 
etc. Then represent the board as an array of 128 squares (of which 64 correspond 
to actual squares on the board). The advantages of this representation are (1) 
it speeds up the program a little by using only one index instead of two in the 
array references, and (2) you can test really quickly and easily whether a move 
stays on the board: i is a legal board position if and only if (i&amp;0x88)==0. 
[Work it out, moving off the board either overflows the column giving i&amp;0x08 
nonzero, or overflows the row giving i&amp;0x80 nonzero.] This is a pretty 
commonly used technique. 
<P><B>Representation 4: bitboards</B>. I'll go into this in a lot more length 
than the other representations because it's probably more unfamiliar, but I 
think it's also likely to work better. Instead of having an array of squares, 
each containing a piece types, have an array of piece types, each of which 
stores a packed array of bits listing the squares containing that piece. Since 
there are 64 possible squares, each of these packed arrays can be stored in a 
64-bit number (two 32-bit words). The big advantage is that you can perform 
certain evaluation and move generation operations very quickly using bitwise 
Boolean operations. Think of it as a way of getting your computer to do 
massively parallel computations by packing things into long words. For example, 
in the following position: 
<P>
<CENTER><IMG src="ICS 180, April 8, 1997.files/970408.gif"></CENTER>
<P>The bitboard for the white pawns (call this 64-bit value "wP") would consist 
of the bits <PRE>    0 0 0 0 0 0 0 0
    0 0 0 0 0 0 0 0
    0 0 0 0 0 1 0 0
    0 0 0 0 0 1 0 0
    0 0 0 0 1 0 0 0
    0 0 0 0 0 0 0 0
    1 1 1 0 0 0 0 1
    0 0 0 0 0 0 0 0
</PRE>Then the bitboard squares occupied by black can be computed by a formula <PRE>    bOcc = bP | bN | bB | bR | bQ | bK
</PRE>(where bP etc are bitboards for the different kinds of black pieces). 
Similarly we can compute the white occupied squares, and or these two bitboards 
together to get all occupied squares. The bitboard of possible white pawn 
one-square move destinations can then be computed by a formula: <PRE>    single_pawn_moves = (wP &lt;&lt; 8) &amp; ~occupied
</PRE>Let's look at this in slow motion. Shifting wP by 8 produces a bitboard of 
positions one place in front of each pawn: <PRE>    0 0 0 0 0 0 0 0
    0 0 0 0 0 1 0 0
    0 0 0 0 0 1 0 0
    0 0 0 0 1 0 0 0
    0 0 0 0 0 0 0 0
    1 1 1 0 0 0 0 1
    0 0 0 0 0 0 0 0
    0 0 0 0 0 0 0 0
</PRE>The negation of occupied gives a bitboard of empty squares: <PRE>    0 0 1 1 0 0 1 0
    1 0 1 0 1 0 0 0
    1 1 1 0 0 0 1 1
    1 0 1 1 1 0 1 1
    1 0 1 1 0 1 1 1
    1 0 1 1 1 0 1 1
    0 0 0 1 1 1 1 0
    0 1 0 1 0 0 1 0
</PRE>The bitwise and of these two bitboards then gives the positions in front 
of a pawn, that are not already occupied: <PRE>    0 0 0 0 0 0 0 0
    0 0 0 0 0 0 0 0
    0 0 0 0 0 0 0 0
    0 0 0 0 1 0 0 0
    0 0 0 0 0 0 0 0
    1 0 1 0 0 0 0 1
    0 0 0 0 0 0 0 0
    0 0 0 0 0 0 0 0
</PRE>Similarly you can find two-square pawn moves by taking the bitboard of 
one-square moves, shifting it another 8 bits, anding it with the non-occupied 
squares again, and anding it with a constant bitboard (shown below) of the 
squares on the fourth row (the only row onto which pawns are allowed to move two 
squares): <PRE>    0 0 0 0 0 0 0 0
    0 0 0 0 0 0 0 0
    0 0 0 0 0 0 0 0
    0 0 0 0 0 0 0 0
    1 1 1 1 1 1 1 1
    0 0 0 0 0 0 0 0
    0 0 0 0 0 0 0 0
    0 0 0 0 0 0 0 0
</PRE>Note that this constant bitboard can be generated at compile time rather 
than each time we want to generate moves. Pawn captures are similar (shift by 
seven or nine, and with a constant to eliminate captures off the left and right 
side of the board, and with bOcc). 
<P>The point of this technique is not that your code is simpler when you program 
with bitboards (it's a little more complicated) but that you generate the pawn 
moves all at once rather than one at a time. Also, a lot of the intermediate 
expressions you need (such as bOcc) get used over and over, and only need to be 
computed once. So bitboards end up being very efficient, and I think would be 
even better for games other than chess in which there are fewer types of pieces. 

<P>One complication arises: it's often important to count the number of nonzero 
bits in a bitboard, or to find a nonzero bit (e.g. to turn the bitboard of 
possible pawn moves into an explicit list of moves). Counting can be done one 
byte at a time, looking up in a 256-entry table the number of nonzero bits in 
each byte. There's a cute trick for finding a single nonzero bit: x^(x-1) (where 
the uparrow is C notation for exclusive or) gives a binary number ...000111... 
where the first one of x^(x-1) is the last nonzero bit of x. If you need to turn 
this into an actual bit, take the result modulo some carefully chosen number M 
(for which the numbers ...000111... are all different mod M), and look the 
result up in a table. As a simple example, the following code finds the index of 
the last nonzero bit of a byte: <PRE>    int T = { -1, 0, 7, 1, 3, -1, 6, 2, 5, 4, -1, -1 };
    int last_bit(unsigned char b) { return T[(b^(b-1)) % 11]; }
</PRE>
<H3>How to Undo?</H3>Remember we said our board representation needed to handle 
undo operations. There are two possible methods: (1) Keep a stack in which each 
stack item holds a whole board representation; to make a move push it on the 
stack and to undo a move pop the stack. Probably this is too slow... (2) Keep a 
stack storing only the move itself together with enough extra information to 
undo the move and restore all the information in the board position. E.g. in 
chess you would need to store the identity of a captured piece (if any) and 
enough information to restore castling and en passant capturing privileges. 
<H3>Repetition Detection</H3>Some games e.g. Go, Chess have special rules about 
what happens when the same position is repeated (in chess, third repetition of a 
position gives the player making the repetition the right to declare a draw). 
How to tell? Short answer: make a hash function translating the position to a 
reasonably large number (we'll talk more about this later because this is also 
very important for speeding up the search). Then keep a list of the hash codes 
for previous game positions and test if your position shows up in it. Typical 
hash function: make 64*13 table of large random numbers; when piece x is on 
position y, look up table[x,y] and add it to hash ignoring overflow [Zobrist]. 
Note that, when making a move of a piece y from positions x to z, you can update 
the hash very quickly: just subtract table[x,y] and add table[z,y]. 
<HR>
<A href="http://www.ics.uci.edu/~eppstein/">David Eppstein, <A 
href="http://www.ics.uci.edu/">Dept. Information &amp; Computer Science</A>, <A 
href="http://www.uci.edu/">UC Irvine</A>, Monday, 14-Apr-1997 11:31:24 PDT. 
</BODY></HTML>

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
美国三级日本三级久久99| 国产精品久久免费看| 亚洲国产精品影院| 欧美亚一区二区| 成年人国产精品| 国产精品久久久久永久免费观看| 成人精品高清在线| 亚洲人成伊人成综合网小说| 色婷婷av一区二区三区gif| 日韩欧美在线影院| 国产一区二区三区免费在线观看| 久久网站热最新地址| 成人午夜在线播放| 亚洲一区二区欧美日韩| 制服丝袜亚洲播放| 国产一区二区日韩精品| 中文字幕一区二区三| 在线观看91精品国产入口| 丝袜a∨在线一区二区三区不卡| 日韩一二三四区| 国产999精品久久久久久绿帽| 亚洲人成亚洲人成在线观看图片| 欧美性生活大片视频| 精品一区二区三区在线观看| 国产精品你懂的| 欧美人成免费网站| 国产福利精品导航| 亚洲一区电影777| 精品久久久久久最新网址| 成人免费看片app下载| 成人精品视频.| 亚洲国产精品嫩草影院| 久久久影视传媒| 91精品办公室少妇高潮对白| 免费在线欧美视频| 国产精品美女久久久久av爽李琼| 欧美私模裸体表演在线观看| 黄色日韩三级电影| 夜夜亚洲天天久久| 国产亚洲欧美日韩日本| 欧美日韩国产综合一区二区| 国产一区二区美女诱惑| 亚洲成人午夜电影| 国产精品电影院| 亚洲精品在线网站| 欧美色成人综合| 成人性生交大合| 久久国产精品99久久久久久老狼| 一区在线观看视频| 亚洲精品在线电影| 欧美日韩aaa| 一本色道亚洲精品aⅴ| 国产成人亚洲综合a∨婷婷图片| 亚洲图片有声小说| ...中文天堂在线一区| 久久人人97超碰com| 91麻豆精品国产91久久久使用方法| 99久久免费国产| 国产成人精品一区二区三区四区| 日韩在线一区二区三区| 一区二区高清在线| 国产精品嫩草久久久久| 久久人人爽人人爽| 欧美zozo另类异族| 日韩免费观看2025年上映的电影| 欧美亚洲综合一区| 91视频观看视频| 99精品在线免费| 成人黄色777网| 风流少妇一区二区| 丰满白嫩尤物一区二区| 国产成人鲁色资源国产91色综| 日韩av一区二区三区| 亚洲成人资源在线| 性做久久久久久| 亚洲成a人在线观看| 亚洲综合清纯丝袜自拍| 亚洲综合一区二区精品导航| 依依成人精品视频| 一区二区三区精品在线| 一区二区高清免费观看影视大全| 亚洲精品久久7777| 亚洲美女免费视频| 亚洲黄色录像片| 亚洲综合一区二区三区| 亚洲国产精品人人做人人爽| 亚洲成av人在线观看| 亚洲电影你懂得| 亚洲成av人影院| 日韩在线播放一区二区| 另类综合日韩欧美亚洲| 久久精品国产久精国产爱| 韩国三级在线一区| 成人的网站免费观看| 色婷婷精品久久二区二区蜜臂av| 色婷婷香蕉在线一区二区| 欧美视频在线播放| 欧美一区二区视频在线观看2020 | 欧美特级限制片免费在线观看| 色呦呦网站一区| 欧美在线视频日韩| 欧美一二三区在线观看| 久久久久久久久久久99999| 国产精品美女久久久久久久久| 综合分类小说区另类春色亚洲小说欧美| 最新国产成人在线观看| 香蕉成人伊视频在线观看| 裸体健美xxxx欧美裸体表演| 国产一区二区三区四| 91丨国产丨九色丨pron| 欧美三级视频在线| 精品日韩一区二区三区免费视频| 欧美激情一区二区三区四区| 亚洲精品日韩一| 奇米精品一区二区三区四区| 国产高清视频一区| 欧洲国内综合视频| 欧美成va人片在线观看| 亚洲日本免费电影| 蜜桃视频一区二区三区在线观看| 国产aⅴ综合色| 欧美在线高清视频| 国产亚洲va综合人人澡精品| 亚洲国产视频一区| 国产一区在线精品| 欧美性一二三区| 国产日韩在线不卡| 视频在线观看一区| 99热这里都是精品| 日韩欧美国产成人一区二区| 亚洲欧美怡红院| 狠狠色伊人亚洲综合成人| 欧洲一区二区av| 欧美国产欧美亚州国产日韩mv天天看完整| 一区二区三区久久久| 国产在线日韩欧美| 欧美男人的天堂一二区| 国产精品传媒入口麻豆| 理论片日本一区| 在线观看欧美精品| 国产精品毛片高清在线完整版| 欧美aaaaa成人免费观看视频| 91在线丨porny丨国产| 久久久综合视频| 日本最新不卡在线| 欧美视频一区二区在线观看| 国产精品欧美一区二区三区| 久久精品国产99| 欧美精品日韩精品| 亚洲午夜国产一区99re久久| 成人av先锋影音| 久久精品一区四区| 紧缚捆绑精品一区二区| 欧美久久久久久久久中文字幕| 日韩一区中文字幕| 成人免费观看男女羞羞视频| 久久视频一区二区| 久草热8精品视频在线观看| 欧美三级视频在线观看| 一区二区三区精品视频| 9l国产精品久久久久麻豆| 久久精品水蜜桃av综合天堂| 久久电影网站中文字幕| 日韩视频在线你懂得| 日本最新不卡在线| 91精品国产综合久久福利 | 欧美精品一区二区三区一线天视频| 性感美女久久精品| 欧美日韩一区久久| 午夜久久久久久久久久一区二区| 91丝袜高跟美女视频| 亚洲男人的天堂在线观看| 91丨porny丨国产| 亚洲精品菠萝久久久久久久| 色综合久久66| 亚洲高清视频在线| 69堂精品视频| 久久国产人妖系列| 久久一二三国产| 丰满亚洲少妇av| 亚洲欧美激情在线| 色综合久久综合| 亚洲午夜激情av| 555www色欧美视频| 久久99热这里只有精品| 2020国产精品久久精品美国| 国产成人综合亚洲网站| 亚洲欧美综合在线精品| 欧美亚洲禁片免费| 美女视频免费一区| 国产亚洲午夜高清国产拍精品 | 亚洲国产日韩在线一区模特| 欧美色综合天天久久综合精品| 五月天婷婷综合| 精品成人a区在线观看| 成人午夜在线视频| 亚洲国产欧美在线人成| 日韩午夜中文字幕| 成人福利在线看| 亚洲成av人片在线|