QB懷舊——25年前的黑白棋程序

最早在電腦學寫程序還是用的GW-BASIC,還是帶行號的,記得編輯也不方便。

不久就接觸到了QB。只買了套上中下三本Quick Basic 4.0 語言參考手冊,開始了QB之旅。

一晃25年過去了,DOS也早塵封成渣渣。想懷舊,還好現在有幾乎完全復現QB那IDE的開源跨平臺軟件QB64。一起動,那熟悉親切的大藍底,看久了眼暈,哈

當年廠商咋喜歡那個配色呢

現在派生自QB語法的開源跨平臺BASIC編譯器,活躍有知名度的還有兩家,FreeBASIC和BlitzMax。不過發展下來也是方言了,用來編譯原先QB4.0下寫的源碼就不太靈了。幹這活還是得QB64,幾乎完全兼容和復現!!!

好了,貼個我當年寫的一個程序,OTHELLO.BAS

CONST COPYRIGHTNUMBER = "HeiBaiQi V1.0"

CONST COPYRIGHT = "Copyright (C) sosei"

CONST NO = "2CFD4E6D12DA4469"

CONST PROGRAMNAME = "OTHELLO"

CONST REGCODELEN = 16

CONST COMPUTERNAME = "Snowman"

CONST E = 2.718281828459045#

CONST PI = 3.141592653589793#

CONST DEGREE = PI / 180

CONST CIRCLEANGLE = 2 * PI

CONST SECOND = 1, MINUTE = 60, HOUR = 60, HALFDAY = 12

CONST DAY = 2& * HALFDAY * HOUR * MINUTE * SECOND

CONST BOARDSIZE = 8

CONST MAXUNITIME = 2 * MINUTE, MAXEXTRATIME = 6 * MINUTE

CONST WARNTIME = 10 * SECOND

CONST HUMAN = 0, COMPUTER = 1

CONST OVER = -1, BLACKSIDE = 0, WHITESIDE = 1

CONST BLACKWIN = -1, EQUAL = 0, WHITEWIN = 1

CONST BLANK = -1, BLACKSTONE = 0, WHITESTONE = 1

CONST BEFORETIME = 0, NOWTIME = 1

CONST ORIGINALSCREEN = -1, BLACKSTATESCREEN = 0, WHITESTATESCREEN = 1, BOARDSCREEN = 2, BUTTONSCREEN = 3

CONST EVENTOFF = -1, EVENTSTOP = 0, EVENTON = 1

CONST TRAPINIT = -1, TRAPOFF = 0, TRAPON = 1

CONST SET = 0, USE = 1

CONST TRUE = -1, FALSE = 0

CONST SHOW = 1, DISAPPEAR = 0

CONST REPOSE = 0, THINK = 1, LOSE = 2, QUIET = 3, WIN = 4

CONST INIT = 0, REST = 1, TURN = 2

CONST FINISH = -1, RENEW = 0

CONST BLACK = 0, WHITE = 3, RED = 2, BLUE = 1

CONST ZEROOFCLOCKANGLE = PI / 2

CONST C = 4294967296#

TYPE playdata

    playname AS STRING * 10

    playtype AS INTEGER

END TYPE

DECLARE FUNCTION RandomNum# ()

DECLARE FUNCTION ERandomNum# (n AS DOUBLE)

DECLARE FUNCTION PIRandomNum# (n AS DOUBLE)

DECLARE FUNCTION PasswordSwitch# (password AS DOUBLE)

DECLARE SUB PasswordToPAB (password AS STRING, passworda AS DOUBLE, passwordb AS DOUBLE)

DECLARE FUNCTION HexToDec# (hexstr AS STRING)

DECLARE SUB DataLock (datastring AS STRING, password AS STRING)

DECLARE SUB DataUnLock (datastring AS STRING, password AS STRING)

DECLARE FUNCTION Verify$ (filenum AS INTEGER, startadd AS LONG, endadd AS LONG)

DECLARE FUNCTION TestCode ()

DECLARE SUB RandomSide (gameorder AS INTEGER, bothname() AS playdata)

DECLARE SUB InputName (humanside AS INTEGER, bothname() AS playdata)

DECLARE SUB othelloscreen (screentype AS INTEGER, screenstate AS INTEGER)

DECLARE SUB trapcontrol (control AS INTEGER)

DECLARE SUB boardinit (board() AS INTEGER)

DECLARE SUB stonenumshow (board() AS INTEGER, stonenum() AS INTEGER)

DECLARE SUB faceshow (nowside AS INTEGER, facetype AS INTEGER)

DECLARE SUB clock (nowside AS INTEGER, clockstate AS INTEGER, recoverscreen AS INTEGER, unitime() AS LONG, extratime() AS LONG, notime AS INTEGER)

DECLARE SUB turnstone (board() AS INTEGER, x AS INTEGER, y AS INTEGER)

DECLARE SUB overjudge (nowside AS INTEGER, board() AS INTEGER)

DECLARE SUB humanthink (nowside AS INTEGER, board() AS INTEGER, x AS INTEGER, y AS INTEGER)

DECLARE SUB computerthink (nowside AS INTEGER, board() AS INTEGER, x AS INTEGER, y AS INTEGER)

DECLARE SUB stoneshow (stone AS INTEGER, x AS INTEGER, y AS INTEGER)

DECLARE SUB lightmark (nowside AS INTEGER, background AS INTEGER, x AS INTEGER, y AS INTEGER, cursor AS INTEGER)

DECLARE FUNCTION CheckPlace (nowside AS INTEGER, board() AS INTEGER, x AS INTEGER, y AS INTEGER)

DECLARE FUNCTION winsidejudge (nowside AS INTEGER, notime AS INTEGER, accpetlose AS INTEGER, stonenum() AS INTEGER)

DECLARE SUB winshow (winside AS INTEGER)

DECLARE SUB AdmitDefeat (accpetlose AS INTEGER)

DECLARE SUB Quit (choose AS INTEGER)

DECLARE SUB Recorder (bothname() AS playdata)

DIM nn AS STRING

DIM nowscreen AS INTEGER

DIM gameorder AS INTEGER

DIM timetrap AS INTEGER

DIM keytrap AS INTEGER

DIM bothname(BLACKSIDE TO WHITESIDE) AS playdata

DIM stonenum(BLACKSIDE TO WHITESIDE) AS INTEGER

DIM unitime(BLACKSIDE TO WHITESIDE, BEFORETIME TO NOWTIME) AS LONG

DIM extratime(BLACKSIDE TO WHITESIDE, BEFORETIME TO NOWTIME) AS LONG

DIM notime AS INTEGER

DIM accpetlose AS INTEGER

DIM board(1 TO BOARDSIZE, 1 TO BOARDSIZE) AS INTEGER

DIM nowside AS INTEGER

DIM x AS INTEGER

DIM y AS INTEGER

DIM winside AS INTEGER

DIM choose AS INTEGER

nn = STRING$(INT(LOG(BOARDSIZE * BOARDSIZE) / LOG(10#)) + 1, "#")

nowscreen = ORIGINALSCREEN

gameorder = 0

SCREEN 1

PLAY "mb"

ON TIMER(SECOND) GOSUB clocklabel

ON KEY(10) GOSUB keylabel

DO

    CLS

    TIMER OFF

    timetrap = EVENTOFF

    KEY(10) OFF

    keytrap = EVENTOFF

    CALL trapcontrol(TRAPINIT)

    LOCATE 25, 3: PRINT COPYRIGHTNUMBER; "  "; COPYRIGHT;

    CALL RandomSide(gameorder, bothname())

    stonenum(BLACKSIDE) = 0

    stonenum(WHITESIDE) = 0

    LOCATE 1, 1: PRINT "Name:"; bothname(BLACKSIDE).playname

    LOCATE 2, 1: PRINT USING "Stones:" + nn; stonenum(BLACKSIDE);

    CALL othelloscreen(BLACKSTATESCREEN, SET)

    CALL faceshow(BLACKSIDE, REPOSE)

    CALL clock(BLACKSIDE, INIT, FALSE, unitime(), extratime(), notime)

    LOCATE 11, 1: PRINT "Name:"; bothname(WHITESIDE).playname

    LOCATE 12, 1: PRINT USING "Stones:" + nn; stonenum(WHITESIDE);

    CALL othelloscreen(WHITESTATESCREEN, SET)

    CALL faceshow(WHITESIDE, REPOSE)

    CALL clock(WHITESIDE, INIT, FALSE, unitime(), extratime(), notime)

    CALL othelloscreen(BOARDSCREEN, SET)

    LOCATE 21, 1: PRINT "F10=Defeat";

    LOCATE 22, 19: PRINT "No:"; NO;

    IF gameorder = 0 THEN

        IF bothname(BLACKSIDE).playtype = HUMAN THEN

            CALL InputName(BLACKSIDE, bothname())

        END IF

        IF bothname(WHITESIDE).playtype = HUMAN THEN

            CALL InputName(WHITESIDE, bothname())

        END IF

    END IF

    CALL boardinit(board())

    FOR x = 1 TO BOARDSIZE

        FOR y = 1 TO BOARDSIZE

            CALL stoneshow(board(x, y), x, y)

        NEXT y

    NEXT x

    CALL stonenumshow(board(), stonenum())

    nowside = BLACKSIDE

    accpetlose = FALSE

    x = 4

    y = 4

    CALL Recorder(bothname())

    gameorder = gameorder + 1

    keytrap = EVENTON

    KEY(10) ON

    PLAY "c8d8"

    DO UNTIL nowside = OVER

        CALL faceshow(nowside, THINK)

        IF bothname(nowside).playtype = HUMAN THEN

            CALL humanthink(nowside, board(), x, y)

        ELSEIF bothname(nowside).playtype = COMPUTER THEN

            CALL computerthink(nowside, board(), x, y)

        END IF

        CALL clock(nowside, REST, FALSE, unitime(), extratime(), notime)

        CALL faceshow(nowside, REPOSE)

        CALL turnstone(board(), x, y)

        CALL stonenumshow(board(), stonenum())

        CALL overjudge(nowside, board())

    LOOP

    overlabel:

    TIMER OFF

    timetrap = EVENTOFF

    KEY(10) OFF

    keytrap = EVENTOFF

    winside = winsidejudge(nowside, notime, accpetlose, stonenum())

    CALL winshow(winside)

    CALL Recorder(bothname())

    CALL Quit(choose)

LOOP UNTIL choose = FINISH

PLAY "mf"

SCREEN 0

CLS

END

clocklabel:

timetrap = EVENTSTOP

CALL clock(nowside, TURN, TRUE, unitime(), extratime(), notime)

IF notime = FALSE THEN

    timetrap = EVENTON

    RETURN

ELSEIF notime = TRUE THEN

    timetrap = EVENTOFF

    RETURN overlabel

END IF

keylabel:

keytrap = EVENTOFF

KEY(10) OFF

CALL AdmitDefeat(accpetlose)

IF accpetlose = FALSE THEN

    keytrap = EVENTON

    RETURN

ELSEIF accpetlose = TRUE THEN

    keytrap = EVENTOFF

    RETURN overlabel

END IF

SUB AdmitDefeat (accpetlose AS INTEGER)

    CONST TWINKLETIME = 1 / 6

    DIM RefTime AS SINGLE

    DIM TimeBalance AS SINGLE

    DIM cw AS STRING * 1

    DIM ct AS STRING * 1

    DIM check AS STRING

    LOCATE 23, 1

    PRINT SPACE$(40);

    cw = "?"

    ct = " "

    RefTime = TIMER

    DO

        LOCATE 23, 1: PRINT "Admit defeat(Y/N)" + cw;

        TimeBalance = TIMER - RefTime

        TimeBalance = TimeBalance + DAY

        TimeBalance = TimeBalance - FIX(TimeBalance / DAY) * DAY

        IF TimeBalance >= TWINKLETIME THEN

            SWAP cw, ct

            RefTime = TIMER

        END IF

        check = INKEY$

    LOOP UNTIL check = "Y" OR check = "y" OR check = "N" OR check = "n"

    LOCATE 23, 1: PRINT "Admit defeat(Y/N)?" + check;

    IF check = "Y" OR check = "y" THEN

        accpetlose = TRUE

    ELSEIF check = "N" OR check = "n" THEN

        accpetlose = FALSE

    END IF

    LOCATE 23, 1

    PRINT SPACE$(40);

END SUB

SUB boardinit (board() AS INTEGER)

    DIM x AS INTEGER

    DIM y AS INTEGER

    FOR x = 1 TO BOARDSIZE

        FOR y = 1 TO BOARDSIZE

            board(x, y) = BLANK

        NEXT y

    NEXT x

    board(BOARDSIZE / 2, BOARDSIZE / 2 + 1) = BLACKSTONE

    board(BOARDSIZE / 2 + 1, BOARDSIZE / 2 + 1) = WHITESTONE

    board(BOARDSIZE / 2, BOARDSIZE / 2) = WHITESTONE

    board(BOARDSIZE / 2 + 1, BOARDSIZE / 2) = BLACKSTONE

END SUB

FUNCTION CheckPlace (nowside AS INTEGER, board() AS INTEGER, x AS INTEGER, y AS INTEGER)

    DIM stone AS INTEGER

    DIM xplus AS INTEGER

    DIM yplus AS INTEGER

    DIM xpointer AS INTEGER

    DIM ypointer AS INTEGER

    IF nowside = BLACKSIDE THEN

        stone = BLACKSTONE

    ELSEIF nowside = WHITESIDE THEN

        stone = WHITESTONE

    END IF

    FOR xplus = -1 TO 1

        FOR yplus = -1 TO 1

            xpointer = x + xplus

            ypointer = y + yplus

            DO WHILE (xpointer >= 1 AND xpointer <= BOARDSIZE) AND (ypointer >= 1 AND ypointer <= BOARDSIZE)

                IF board(xpointer, ypointer) = stone THEN

                    IF x + xplus <> xpointer OR y + yplus <> ypointer THEN

                        CheckPlace = TRUE

                        EXIT FUNCTION

                    ELSE

                        EXIT DO

                    END IF

                ELSEIF board(xpointer, ypointer) = BLANK THEN

                    EXIT DO

                END IF

                xpointer = xpointer + xplus

                ypointer = ypointer + yplus

            LOOP

        NEXT yplus

    NEXT xplus

    CheckPlace = FALSE

END FUNCTION

SUB clock (nowside AS INTEGER, clockstate AS INTEGER, recoverscreen AS INTEGER, unitime() AS LONG, extratime() AS LONG, notime AS INTEGER) STATIC

    CONST SA = CIRCLEANGLE / MINUTE

    CONST MA = CIRCLEANGLE / HOUR

    CONST HA = CIRCLEANGLE / HALFDAY

    SHARED nowscreen AS INTEGER

    DIM unitclockface AS INTEGER

    DIM unitclockpointer AS INTEGER

    DIM extraclockface AS INTEGER

    DIM extraclockpointer AS INTEGER

    DIM befscreen AS INTEGER

    DIM a AS SINGLE

    DIM ot AS INTEGER

    DIM nt AS INTEGER

    DIM os AS INTEGER

    DIM om AS INTEGER

    DIM oh AS INTEGER

    DIM unitsecond(BLACKSIDE TO WHITESIDE) AS INTEGER

    DIM unitminute(BLACKSIDE TO WHITESIDE) AS INTEGER

    DIM unithour(BLACKSIDE TO WHITESIDE) AS INTEGER

    DIM extrasecond(BLACKSIDE TO WHITESIDE) AS INTEGER

    DIM extraminute(BLACKSIDE TO WHITESIDE) AS INTEGER

    DIM extrahour(BLACKSIDE TO WHITESIDE) AS INTEGER


    IF clockstate = INIT THEN

        unitime(nowside, BEFORETIME) = -1

        unitime(nowside, NOWTIME) = MAXUNITIME

        extratime(nowside, BEFORETIME) = -1

        extratime(nowside, NOWTIME) = MAXEXTRATIME

        notime = FALSE

        unitclockface = TRUE: unitclockpointer = TRUE

        extraclockface = TRUE: extraclockpointer = TRUE

    ELSEIF clockstate = REST THEN

        unitime(nowside, BEFORETIME) = unitime(nowside, NOWTIME)

        unitime(nowside, NOWTIME) = MAXUNITIME

        unitclockface = FALSE: unitclockpointer = TRUE

        extraclockface = FALSE: extraclockpointer = FALSE

    ELSEIF clockstate = TURN THEN

        IF unitime(nowside, NOWTIME) > 0 THEN

            unitime(nowside, BEFORETIME) = unitime(nowside, NOWTIME)

            unitime(nowside, NOWTIME) = unitime(nowside, NOWTIME) - SECOND

            unitclockface = FALSE: unitclockpointer = TRUE

            extraclockface = FALSE: extraclockpointer = FALSE

        ELSEIF unitime(nowside, NOWTIME) = 0 THEN

            extratime(nowside, BEFORETIME) = extratime(nowside, NOWTIME)

            extratime(nowside, NOWTIME) = extratime(nowside, NOWTIME) - SECOND

            unitclockface = FALSE: unitclockpointer = FALSE

            extraclockface = FALSE: extraclockpointer = TRUE

            IF extratime(nowside, NOWTIME) = 0 THEN

                notime = TRUE

            END IF

        END IF

    END IF

    IF recoverscreen = TRUE THEN

        befscreen = nowscreen

    END IF

    IF nowside = BLACKSIDE THEN

        CALL othelloscreen(BLACKSTATESCREEN, USE)

    ELSEIF nowside = WHITESIDE THEN

        CALL othelloscreen(WHITESTATESCREEN, USE)

    END IF

    IF unitclockface = TRUE THEN

        CIRCLE (11, 11), 10, WHITE: PAINT (11, 11), BLACK, WHITE

        CIRCLE (11, 11), .5, WHITE

        FOR a = ZEROOFCLOCKANGLE TO ZEROOFCLOCKANGLE - CIRCLEANGLE STEP -(CIRCLEANGLE / HALFDAY)

            LINE (9 * COS(a) + 11, 9 * SIN(a) + 11)-(8.5 * COS(a) + 11, 8.5 * SIN(a) + 11), WHITE

        NEXT a

    END IF

    IF unitclockpointer = TRUE THEN

        IF unitime(nowside, NOWTIME) < WARNTIME THEN

            IF unitime(nowside, NOWTIME) < MAXUNITIME THEN

                PLAY "c8"

            END IF

        END IF

        ot = unitime(nowside, BEFORETIME)

        nt = unitime(nowside, NOWTIME)

        IF nt <> ot THEN

            os = ot MOD MINUTE

            unitsecond(nowside) = nt MOD MINUTE

            a = ZEROOFCLOCKANGLE - SA * os

            LINE (1 * COS(a) + 11, 1 * SIN(a) + 11)-(7 * COS(a) + 11, 7 * SIN(a) + 11), BLACK

            ot = INT(ot / MINUTE)

            nt = INT(nt / MINUTE)

            IF nt <> ot THEN

                om = ot MOD HOUR

                unitminute(nowside) = nt MOD HOUR

                a = ZEROOFCLOCKANGLE - MA * om

                LINE (1 * COS(a) + 11, 1 * SIN(a) + 11)-(6 * COS(a) + 11, 6 * SIN(a) + 11), BLACK

                ot = INT(ot / HOUR)

                nt = INT(nt / HOUR)

                IF nt <> ot THEN

                    oh = ot MOD HALFDAY

                    unithour(nowside) = nt MOD HALFDAY

                    a = ZEROOFCLOCKANGLE - HA * oh

                    LINE (1 * COS(a) + 11, 1 * SIN(a) + 11)-(4.5 * COS(a) + 11, 4.5 * SIN(a) + 11), BLACK

                END IF

            END IF

            a = ZEROOFCLOCKANGLE - SA * unitsecond(nowside)

            LINE (1 * COS(a) + 11, 1 * SIN(a) + 11)-(7 * COS(a) + 11, 7 * SIN(a) + 11), RED

            a = ZEROOFCLOCKANGLE - MA * unitminute(nowside)

            LINE (1 * COS(a) + 11, 1 * SIN(a) + 11)-(6 * COS(a) + 11, 6 * SIN(a) + 11), BLUE

            a = ZEROOFCLOCKANGLE - HA * unithour(nowside)

            LINE (1 * COS(a) + 11, 1 * SIN(a) + 11)-(4.5 * COS(a) + 11, 4.5 * SIN(a) + 11), WHITE

        END IF

    END IF

    IF extraclockface = TRUE THEN

        CIRCLE (35, 15.5), 14, WHITE: PAINT (35, 15.5), BLACK, WHITE

        CIRCLE (35, 15.5), .5, WHITE

        FOR a = ZEROOFCLOCKANGLE TO ZEROOFCLOCKANGLE - CIRCLEANGLE STEP -(CIRCLEANGLE / HALFDAY)

            LINE (13.5 * COS(a) + 35, 13.5 * SIN(a) + 15.5)-(12 * COS(a) + 35, 12 * SIN(a) + 15.5), WHITE

        NEXT a

    END IF

    IF extraclockpointer = TRUE THEN

        ot = extratime(nowside, BEFORETIME)

        nt = extratime(nowside, NOWTIME)

        IF nt <> ot THEN

            os = ot MOD MINUTE

            extrasecond(nowside) = nt MOD MINUTE

            IF extrasecond(nowside) = 0 THEN

                IF extratime(nowside, NOWTIME) < MAXEXTRATIME THEN

                    PLAY "e8"

                END IF

            END IF

            a = ZEROOFCLOCKANGLE - SA * os

            LINE (1 * COS(a) + 35, 1 * SIN(a) + 15.5)-(11 * COS(a) + 35, 11 * SIN(a) + 15.5), BLACK

            ot = INT(ot / MINUTE)

            nt = INT(nt / MINUTE)

            IF nt <> ot THEN

                om = ot MOD HOUR

                extraminute(nowside) = nt MOD HOUR

                a = ZEROOFCLOCKANGLE - MA * om

                LINE (1 * COS(a) + 35, 1 * SIN(a) + 15.5)-(9 * COS(a) + 35, 9 * SIN(a) + 15.5), BLACK

                ot = INT(ot / HOUR)

                nt = INT(nt / HOUR)

                IF nt <> ot THEN

                    oh = ot MOD HALFDAY

                    extrahour(nowside) = nt MOD HALFDAY

                    a = ZEROOFCLOCKANGLE - HA * oh

                    LINE (1 * COS(a) + 35, 1 * SIN(a) + 15.5)-(7 * COS(a) + 35, 7 * SIN(a) + 15.5), BLACK

                END IF

            END IF

            a = ZEROOFCLOCKANGLE - SA * extrasecond(nowside)

            LINE (1 * COS(a) + 35, 1 * SIN(a) + 15.5)-(11 * COS(a) + 35, 11 * SIN(a) + 15.5), RED

            a = ZEROOFCLOCKANGLE - MA * extraminute(nowside)

            LINE (1 * COS(a) + 35, 1 * SIN(a) + 15.5)-(9 * COS(a) + 35, 9 * SIN(a) + 15.5), BLUE

            a = ZEROOFCLOCKANGLE - HA * extrahour(nowside)

            LINE (1 * COS(a) + 35, 1 * SIN(a) + 15.5)-(7 * COS(a) + 35, 7 * SIN(a) + 15.5), WHITE

        END IF

    END IF

    IF recoverscreen = TRUE THEN

        CALL othelloscreen(befscreen, USE)

    END IF

END SUB

SUB computerthink (nowside AS INTEGER, board() AS INTEGER, x AS INTEGER, y AS INTEGER)

    SHARED timetrap AS INTEGER

    DIM Place AS INTEGER

    DIM xx AS INTEGER

    DIM yy AS INTEGER

    Place = FALSE

    timetrap = EVENTON

    TIMER ON

    FOR xx = 1 TO BOARDSIZE

        FOR yy = 1 TO BOARDSIZE

            IF board(xx, yy) = BLANK THEN

                Place = CheckPlace(nowside, board(), xx, yy)

                IF Place = TRUE THEN

                    TIMER OFF

                    timetrap = EVENTOFF

                    x = xx

                    y = yy

                    IF nowside = BLACKSIDE THEN

                        board(x, y) = BLACKSTONE

                    ELSEIF nowside = WHITESIDE THEN

                        board(x, y) = WHITESTONE

                    END IF

                    CALL stoneshow(board(x, y), x, y)

                    EXIT SUB

                END IF

            END IF

        NEXT yy

    NEXT xx

END SUB

SUB DataLock (datastring AS STRING, password AS STRING)

    DIM passworda AS DOUBLE

    DIM passwordb AS DOUBLE

    DIM datalength AS INTEGER

    DIM tm AS DOUBLE

    DIM i AS INTEGER

    DIM byte AS STRING * 1

    DIM add(1 TO 2) AS INTEGER

    DIM bit(1 TO 2) AS STRING * 1

    CALL PasswordToPAB(password, passworda, passwordb)

    datalength = LEN(datastring)

    tm = PIRandomNum#(PasswordSwitch#((passworda)))

    FOR i = 1 TO datalength

        byte = CHR$(ASC(MID$(datastring, i, 1)) XOR FIX(256 * PIRandomNum#(-1)))

        MID$(datastring, i, 1) = byte

    NEXT i

    tm = ERandomNum#(PasswordSwitch#((passwordb)))

    FOR i = 1 TO datalength

        add(1) = FIX(datalength * ERandomNum#(-1) + 1)

        add(2) = FIX(datalength * ERandomNum#(-1) + 1)

        bit(1) = MID$(datastring, add(1), 1)

        bit(2) = MID$(datastring, add(2), 1)

        MID$(datastring, add(1), 1) = bit(2)

        MID$(datastring, add(2), 1) = bit(1)

    NEXT i

    tm = ERandomNum#(PasswordSwitch#((passworda)))

    FOR i = 1 TO datalength

        byte = CHR$(ASC(MID$(datastring, i, 1)) XOR FIX(256 * ERandomNum#(-1)))

        MID$(datastring, i, 1) = byte

    NEXT i

    tm = PIRandomNum#(PasswordSwitch#((passwordb)))

    FOR i = 1 TO datalength

        add(1) = FIX(datalength * PIRandomNum#(-1) + 1)

        add(2) = FIX(datalength * PIRandomNum#(-1) + 1)

        bit(1) = MID$(datastring, add(1), 1)

        bit(2) = MID$(datastring, add(2), 1)

        MID$(datastring, add(1), 1) = bit(2)

        MID$(datastring, add(2), 1) = bit(1)

    NEXT i

    tm = ERandomNum#((passworda))

    tm = PIRandomNum#((passworda))

    FOR i = 1 TO datalength

        add(1) = FIX(datalength * ERandomNum#(-1) + 1)

        add(2) = FIX(datalength * ERandomNum#(-1) + 1)

        bit(1) = MID$(datastring, add(1), 1)

        bit(2) = MID$(datastring, add(2), 1)

        bit(1) = CHR$(ASC(bit(1)) XOR FIX(256 * PIRandomNum#(-1)))

        bit(2) = CHR$(ASC(bit(2)) XOR FIX(256 * PIRandomNum#(-1)))

        MID$(datastring, add(1), 1) = bit(2)

        MID$(datastring, add(2), 1) = bit(1)

    NEXT i

    tm = PIRandomNum#((passwordb))

    tm = ERandomNum#((passwordb))

    FOR i = 1 TO datalength

        add(1) = FIX(datalength * PIRandomNum#(-1) + 1)

        add(2) = FIX(datalength * PIRandomNum#(-1) + 1)

        bit(1) = MID$(datastring, add(1), 1)

        bit(2) = MID$(datastring, add(2), 1)

        bit(1) = CHR$(ASC(bit(1)) XOR FIX(256 * ERandomNum#(-1)))

        bit(2) = CHR$(ASC(bit(2)) XOR FIX(256 * ERandomNum#(-1)))

        MID$(datastring, add(1), 1) = bit(2)

        MID$(datastring, add(2), 1) = bit(1)

    NEXT i

END SUB

SUB DataUnLock (datastring AS STRING, password AS STRING)

    DIM passworda AS DOUBLE

    DIM passwordb AS DOUBLE

    DIM datalength AS INTEGER

    DIM tm AS DOUBLE

    DIM i AS INTEGER

    DIM bit(1 TO 2) AS STRING * 1

    DIM byte AS STRING * 1


    datalength = LEN(datastring)

    DIM add(1 TO datalength, 1 TO 2) AS INTEGER

    DIM rn(1 TO datalength, 1 TO 2) AS STRING * 1


    CALL PasswordToPAB(password, passworda, passwordb)

    tm = PIRandomNum#((passwordb))

    tm = ERandomNum#((passwordb))

    FOR i = 1 TO datalength

        add(1, i) = FIX(datalength * PIRandomNum#(-1) + 1)

        add(2, i) = FIX(datalength * PIRandomNum#(-1) + 1)

        rn(i, 1) = CHR$(FIX(256 * ERandomNum#(-1)))

        rn(i, 2) = CHR$(FIX(256 * ERandomNum#(-1)))

    NEXT i

    FOR i = datalength TO 1 STEP -1

        bit(1) = MID$(datastring, add(i, 2), 1)

        bit(2) = MID$(datastring, add(i, 1), 1)

        bit(1) = CHR$(ASC(bit(1)) XOR ASC(rn(i, 1)))

        bit(2) = CHR$(ASC(bit(2)) XOR ASC(rn(i, 2)))

        MID$(datastring, add(i, 1), 1) = bit(1)

        MID$(datastring, add(i, 2), 1) = bit(2)

    NEXT i

    tm = ERandomNum#((passworda))

    tm = PIRandomNum#((passworda))

    FOR i = 1 TO datalength

        add(i, 1) = FIX(datalength * ERandomNum#(-1) + 1)

        add(i, 2) = FIX(datalength * ERandomNum#(-1) + 1)

        rn(i, 1) = CHR$(FIX(256 * PIRandomNum#(-1)))

        rn(i, 2) = CHR$(FIX(256 * PIRandomNum#(-1)))

    NEXT i

    FOR i = datalength TO 1 STEP -1

        bit(1) = MID$(datastring, add(i, 2), 1)

        bit(2) = MID$(datastring, add(i, 1), 1)

        bit(1) = CHR$(ASC(bit(1)) XOR ASC(rn(i, 1)))

        bit(2) = CHR$(ASC(bit(2)) XOR ASC(rn(i, 2)))

        MID$(datastring, add(i, 1), 1) = bit(1)

        MID$(datastring, add(i, 2), 1) = bit(2)

    NEXT i

    tm = PIRandomNum#(PasswordSwitch#((passwordb)))

    FOR i = 1 TO datalength

        add(i, 1) = FIX(datalength * PIRandomNum#(-1) + 1)

        add(i, 2) = FIX(datalength * PIRandomNum#(-1) + 1)

    NEXT i

    FOR i = datalength TO 1 STEP -1

        bit(1) = MID$(datastring, add(i, 2), 1)

        bit(2) = MID$(datastring, add(i, 1), 1)

        MID$(datastring, add(i, 1), 1) = bit(1)

        MID$(datastring, add(i, 2), 1) = bit(2)

    NEXT i

    tm = ERandomNum#(PasswordSwitch#((passworda)))

    FOR i = 1 TO datalength

        byte = CHR$(ASC(MID$(datastring, i, 1)) XOR FIX(256 * ERandomNum#(-1)))

        MID$(datastring, i, 1) = byte

    NEXT i

    tm = ERandomNum#(PasswordSwitch#((passwordb)))

    FOR i = 1 TO datalength

        add(i, 1) = FIX(datalength * ERandomNum#(-1) + 1)

        add(i, 2) = FIX(datalength * ERandomNum#(-1) + 1)

    NEXT i

    FOR i = datalength TO 1 STEP -1

        bit(1) = MID$(datastring, add(i, 2), 1)

        bit(2) = MID$(datastring, add(i, 1), 1)

        MID$(datastring, add(i, 1), 1) = bit(1)

        MID$(datastring, add(i, 2), 1) = bit(2)

    NEXT i

    tm = PIRandomNum#(PasswordSwitch#((passworda)))

    FOR i = 1 TO datalength

        byte = CHR$(ASC(MID$(datastring, i, 1)) XOR FIX(256 * PIRandomNum#(-1)))

        MID$(datastring, i, 1) = byte

    NEXT i

END SUB

FUNCTION ERandomNum# (n AS DOUBLE)

    STATIC x AS DOUBLE

    SELECT CASE n

        CASE IS >= 0

            x = LOG(n + PI)

        CASE IS < 0

            x = LOG(x * C + PI)

    END SELECT

    x = x / 10 ^ INT(LOG(x) / LOG(10#) - 4)

    x = x - FIX(x)

    ERandomNum# = x

END FUNCTION

SUB faceshow (nowside AS INTEGER, facetype AS INTEGER)

    DIM forecolor AS INTEGER

    DIM backcolor AS INTEGER

    IF nowside = BLACKSIDE THEN

        CALL othelloscreen(BLACKSTATESCREEN, USE)

    ELSEIF nowside = WHITESIDE THEN

        CALL othelloscreen(WHITESTATESCREEN, USE)

    END IF

    IF nowside = BLACKSIDE THEN

        forecolor = WHITE

        backcolor = BLACK

    ELSEIF nowside = WHITESIDE THEN

        forecolor = BLACK

        backcolor = WHITE

    END IF

    CIRCLE (6, 25), 3.9, RED

    PAINT (6, 25), BLUE, RED

    PAINT (6, 25), backcolor, RED

    IF facetype = THINK THEN

        CIRCLE (4.8, 26), .6, forecolor

        CIRCLE (7.2, 26), .6, forecolor

        LINE (5, 23)-(7, 23), forecolor

    ELSEIF facetype = LOSE THEN

        CIRCLE (4.8, 26), .6, forecolor

        CIRCLE (7.2, 26), .6, forecolor

        CIRCLE (6, 21), 2.4, forecolor, 60 * DEGREE, 120 * DEGREE

    ELSEIF facetype = QUIET THEN

        CIRCLE (4.8, 26), .6, forecolor

        CIRCLE (7.2, 26), .6, forecolor

        CIRCLE (6, 23), 1, forecolor, , , .4

    ELSEIF facetype = WIN THEN

        CIRCLE (4.8, 26), .6, forecolor

        CIRCLE (7.2, 26), .6, forecolor

        CIRCLE (6, 25), 2, forecolor, 240 * DEGREE, 300 * DEGREE

    END IF

END SUB

FUNCTION HexToDec# (hexstr AS STRING)

    DIM dec AS DOUBLE

    DIM length AS INTEGER

    DIM i AS INTEGER

    DIM byte AS STRING * 1

    dec = 0

    length = LEN(hexstr)

    FOR i = 1 TO length

        byte = MID$(hexstr, i, 1)

        SELECT CASE byte

            CASE "0" TO "9"

                dec = dec + (ASC(byte) - 48) * 16# ^ (length - i)

            CASE "A" TO "F"

                dec = dec + (ASC(byte) - 55) * 16# ^ (length - i)

        END SELECT

    NEXT i

    HexToDec# = dec

END FUNCTION

SUB humanthink (nowside AS INTEGER, board() AS INTEGER, x AS INTEGER, y AS INTEGER)

    CONST TWINKLETIME = 1 / 3

    SHARED timetrap AS INTEGER

    DIM LeftKey AS STRING * 2

    DIM RightKey AS STRING * 2

    DIM UpKey AS STRING * 2

    DIM DownKey AS STRING * 2

    DIM EnterKey AS STRING * 1

    DIM State AS INTEGER

    DIM RefTime AS SINGLE

    DIM TimeBalance AS SINGLE

    DIM check AS STRING

    DIM Place AS INTEGER

    LeftKey = CHR$(0) + CHR$(75)

    RightKey = CHR$(0) + CHR$(77)

    UpKey = CHR$(0) + CHR$(72)

    DownKey = CHR$(0) + CHR$(80)

    EnterKey = CHR$(13)

    Place = FALSE

    timetrap = EVENTON

    TIMER ON

    DO

        State = SHOW

        CALL lightmark(nowside, board(x, y), x, y, State)

        RefTime = TIMER

        DO

            TimeBalance = TIMER - RefTime

            TimeBalance = TimeBalance + DAY

            TimeBalance = TimeBalance - FIX(TimeBalance / DAY) * DAY

            IF TimeBalance >= TWINKLETIME THEN

                IF State = SHOW THEN

                    State = DISAPPEAR

                ELSEIF State = DISAPPEAR THEN

                    State = SHOW

                END IF

                CALL lightmark(nowside, board(x, y), x, y, State)

                RefTime = TIMER

            END IF

            check = INKEY$

        LOOP WHILE check = ""

        State = DISAPPEAR

        CALL lightmark(nowside, board(x, y), x, y, State)

        LOCATE 23, 1

        PRINT SPACE$(40);

        SELECT CASE check

            CASE LeftKey

                x = x - 1

                IF x < 1 THEN

                    x = BOARDSIZE

                END IF

            CASE RightKey

                x = x + 1

                IF x > BOARDSIZE THEN

                    x = 1

                END IF

            CASE UpKey

                y = y + 1

                IF y > BOARDSIZE THEN

                    y = 1

                END IF

            CASE DownKey

                y = y - 1

                IF y < 1 THEN

                    y = BOARDSIZE

                END IF

            CASE EnterKey

                IF board(x, y) = BLANK THEN

                    Place = CheckPlace(nowside, board(), x, y)

                    IF Place = TRUE THEN

                        TIMER OFF

                        timetrap = EVENTOFF

                        IF nowside = BLACKSIDE THEN

                            board(x, y) = BLACKSTONE

                        ELSEIF nowside = WHITESIDE THEN

                            board(x, y) = WHITESTONE

                        END IF

                        CALL stoneshow(board(x, y), x, y)

                    ELSEIF Place = FALSE THEN

                        LOCATE 23, 1

                        PRINT "No strones capture.";

                        BEEP

                    END IF

                ELSE

                    LOCATE 23, 1

                    PRINT "Occupied square.";

                    BEEP

                END IF

            CASE ELSE

                BEEP

        END SELECT

    LOOP WHILE Place = FALSE

END SUB

SUB InputName (humanside AS INTEGER, bothname() AS playdata)

    CONST BLACKW = 1

    CONST BLACKH = 6

    CONST WHITEW = 11

    CONST WHITEH = 6

    CONST TWINKLETIME = 1 / 6


    DIM w AS INTEGER

    DIM h AS INTEGER

    DIM i AS INTEGER

    DIM RefTime AS SINGLE

    DIM TimeBalance AS SINGLE

    DIM cw AS STRING * 1

    DIM ct AS STRING * 1

    DIM check AS STRING

    DIM humanname AS STRING


    IF humanside = BLACKSIDE THEN

        w = BLACKW

        h = BLACKH

    ELSEIF humanside = WHITESIDE THEN

        w = WHITEW

        h = WHITEH

    END IF

    humanname = ""

    i = 0

    cw = "?"

    ct = " "

    RefTime = TIMER

    DO

        LOCATE w, h: PRINT humanname + cw + SPACE$(10 - i - 1)

        TimeBalance = TIMER - RefTime

        TimeBalance = TimeBalance + DAY

        TimeBalance = TimeBalance - FIX(TimeBalance / DAY) * DAY

        IF TimeBalance >= TWINKLETIME THEN

            SWAP cw, ct

            RefTime = TIMER

        END IF

        check = INKEY$

        IF check >= "A" AND check <= "Z" OR check >= "a" AND check <= "z" OR check = " " OR check = "-" THEN

            humanname = humanname + check

            i = i + 1

        END IF

        IF check = CHR$(8) AND i > 0 THEN

            i = i - 1

            humanname = LEFT$(humanname, i)

        END IF

    LOOP UNTIL i >= 10 OR check = CHR$(13)

    bothname(humanside).playname = humanname

    LOCATE w, h: PRINT bothname(humanside).playname

END SUB

SUB lightmark (nowside AS INTEGER, background AS INTEGER, x AS INTEGER, y AS INTEGER, cursor AS INTEGER)

    CALL trapcontrol(TRAPOFF)

    CALL othelloscreen(BOARDSCREEN, USE)

    IF cursor = SHOW THEN

        IF background = BLANK THEN

            IF nowside = BLACKSIDE THEN

                CIRCLE (x - .5, y - .5), .2, BLACK

                PAINT (x - .5, y - .5), BLACK, BLACK

            ELSEIF nowside = WHITESIDE THEN

                CIRCLE (x - .5, y - .5), .2, WHITE

                PAINT (x - .5, y - .5), WHITE, WHITE

            END IF

        ELSE

            CIRCLE (x - .5, y - .5), .2, RED

            PAINT (x - .5, y - .5), RED, RED

        END IF

    ELSEIF cursor = DISAPPEAR THEN

        IF background = BLANK THEN

            PAINT (x - .5, y - .5), BLUE, BLUE

        ELSEIF background = BLACKSTONE THEN

            PAINT (x - .5, y - .5), BLACK, BLACK

        ELSEIF background = WHITESTONE THEN

            PAINT (x - .5, y - .5), WHITE, WHITE

        END IF

    END IF

    CALL trapcontrol(TRAPON)

END SUB

SUB othelloscreen (screentype AS INTEGER, screenstate AS INTEGER)

    SHARED nowscreen AS INTEGER

    DIM i AS INTEGER

    IF screentype = BLACKSTATESCREEN THEN

        IF screenstate = SET THEN

            nowscreen = BLACKSTATESCREEN

            VIEW (1, 18)-(120, 77), BLUE, WHITE

            WINDOW (1, 1)-(50, 30)

        ELSEIF screenstate = USE AND nowscreen <> BLACKSTATESCREEN THEN

            nowscreen = BLACKSTATESCREEN

            VIEW (1, 18)-(120, 77)

            WINDOW (1, 1)-(50, 30)

        END IF

    ELSEIF screentype = WHITESTATESCREEN THEN

        IF screenstate = SET THEN

            nowscreen = WHITESTATESCREEN

            VIEW (1, 98)-(120, 157), BLUE, WHITE

            WINDOW (1, 1)-(50, 30)

        ELSEIF screenstate = USE AND nowscreen <> WHITESTATESCREEN THEN

            nowscreen = WHITESTATESCREEN

            VIEW (1, 98)-(120, 157)

            WINDOW (1, 1)-(50, 30)

        END IF

    ELSEIF screentype = BOARDSCREEN THEN

        IF screenstate = SET THEN

            nowscreen = BOARDSCREEN

            VIEW (126, 1)-(318, 161), BLUE, WHITE

            WINDOW (0, 0)-(BOARDSIZE, BOARDSIZE)

            FOR i = 0 TO BOARDSIZE

                LINE (i, 0)-(i, BOARDSIZE), BLACK

            NEXT i

            FOR i = 0 TO BOARDSIZE

                LINE (0, i)-(BOARDSIZE, i), BLACK

            NEXT i

        ELSEIF screenstate = USE AND nowscreen <> BOARDSCREEN THEN

            nowscreen = BOARDSCREEN

            VIEW (126, 1)-(318, 161)

            WINDOW (0, 0)-(BOARDSIZE, BOARDSIZE)

        END IF

    ELSEIF screentype = BUTTONSCREEN THEN

    END IF

END SUB

SUB overjudge (nowside AS INTEGER, board() AS INTEGER)

    DIM refnowside AS INTEGER

    DIM x AS INTEGER

    DIM y AS INTEGER


    refnowside = nowside

    DO

        IF nowside = BLACKSIDE THEN

            nowside = WHITESIDE

        ELSEIF nowside = WHITESIDE THEN

            nowside = BLACKSIDE

        END IF

        FOR x = 1 TO BOARDSIZE

            FOR y = 1 TO BOARDSIZE

                IF board(x, y) = BLANK THEN

                    IF CheckPlace(nowside, board(), x, y) = TRUE THEN

                        EXIT SUB

                    END IF

                END IF

            NEXT y

        NEXT x

    LOOP UNTIL nowside = refnowside

    nowside = OVER

END SUB

FUNCTION PasswordSwitch# (password AS DOUBLE)

    DIM i AS INTEGER

    DIM tm AS DOUBLE

    DIM rn AS DOUBLE

    tm = password - FIX(password / 65536) * 65536

    rn = PIRandomNum#((tm))

    rn = ERandomNum#((tm))

    FOR i = 1 TO 16

        IF PIRandomNum#(-1) * 999999 < 500000 THEN

            password = password + FIX(C * PIRandomNum#(-1))

        END IF

        IF ERandomNum#(-1) * 999999 >= 500000 THEN

            password = password + FIX(C * ERandomNum#(-1))

        END IF

    NEXT i

    PasswordSwitch# = password - FIX(password / C) * C

END FUNCTION

SUB PasswordToPAB (password AS STRING, passworda AS DOUBLE, passwordb AS DOUBLE)

    passworda = HexToDec(MID$(password, 1, 4) + MID$(password, 5, 4))

    passwordb = HexToDec(MID$(password, 9, 4) + MID$(password, 13, 4))

END SUB

FUNCTION PIRandomNum# (n AS DOUBLE)

    STATIC x AS DOUBLE

    SELECT CASE n

        CASE IS >= 0

            x = (n + E) ^ PI

        CASE IS < 0

            x = (x * C + E) ^ PI

    END SELECT

    x = x / 10 ^ INT(LOG(x) / LOG(10#) - 4)

    x = x - FIX(x)

    PIRandomNum# = x

END FUNCTION

SUB Quit (choose AS INTEGER)

    CONST TWINKLETIME = 1 / 6


    DIM RefTime AS SINGLE

    DIM TimeBalance AS SINGLE

    DIM cw AS STRING * 1

    DIM ct AS STRING * 1

    DIM check AS STRING

    cw = "?"

    ct = " "

    RefTime = TIMER

    DO

        LOCATE 23, 1: PRINT "Quit(Y/N)" + cw;

        TimeBalance = TIMER - RefTime

        TimeBalance = TimeBalance + DAY

        TimeBalance = TimeBalance - FIX(TimeBalance / DAY) * DAY

        IF TimeBalance >= TWINKLETIME THEN

            SWAP cw, ct

            RefTime = TIMER

        END IF

        check = INKEY$

    LOOP UNTIL check = "Y" OR check = "y" OR check = "N" OR check = "n"

    LOCATE 23, 1: PRINT "Quit(Y/N)?" + check;

    IF check = "Y" OR check = "y" THEN

        choose = FINISH

    ELSEIF check = "N" OR check = "n" THEN

        choose = RENEW

    END IF

    LOCATE 23, 1

    PRINT SPACE$(40);

END SUB

FUNCTION RandomNum#

    DIM rn AS DOUBLE

    DIM rb AS INTEGER

    DIM i AS INTEGER

    DIM j AS LONG

    rn = 0

    RANDOMIZE TIMER

    FOR i = 3 TO 0 STEP -1

        rb = INP(&H40)

        rn = rn + rb * 256# ^ i

        FOR j = 1 TO FIX(65536 * RND + 256)

        NEXT j

    NEXT i

    RandomNum# = rn

END FUNCTION

SUB RandomSide (gameorder AS INTEGER, bothname() AS playdata)

    DIM cl AS STRING

    IF gameorder = 0 THEN

        cl = UCASE$(COMMAND$)

        IF cl = "/C-C" THEN

            bothname(BLACKSIDE).playname = COMPUTERNAME

            bothname(BLACKSIDE).playtype = COMPUTER

            bothname(WHITESIDE).playname = COMPUTERNAME

            bothname(WHITESIDE).playtype = COMPUTER

        ELSEIF cl = "/H-H" THEN

            bothname(BLACKSIDE).playname = ""

            bothname(BLACKSIDE).playtype = HUMAN

            bothname(WHITESIDE).playname = ""

            bothname(WHITESIDE).playtype = HUMAN

        ELSE

            RANDOMIZE TIMER

            IF RND < .5 THEN

                bothname(BLACKSIDE).playname = ""

                bothname(BLACKSIDE).playtype = HUMAN

                bothname(WHITESIDE).playname = COMPUTERNAME

                bothname(WHITESIDE).playtype = COMPUTER

            ELSE

                bothname(BLACKSIDE).playname = COMPUTERNAME

                bothname(BLACKSIDE).playtype = COMPUTER

                bothname(WHITESIDE).playname = ""

                bothname(WHITESIDE).playtype = HUMAN

            END IF

        END IF

    ELSE

        SWAP bothname(BLACKSIDE).playname, bothname(WHITESIDE).playname

        SWAP bothname(BLACKSIDE).playtype, bothname(WHITESIDE).playtype

    END IF

END SUB

SUB Recorder (bothname() AS playdata)

    DIM filename AS STRING

    filename = LEFT$(bothname(BLACKSIDE).playname, 1) + "&" + LEFT$(bothname(WHITESIDE).playname, 1) + "_" + "xxxx" + ".HBQ"

END SUB

SUB stonenumshow (board() AS INTEGER, stonenum() AS INTEGER)

    SHARED nn AS STRING

    DIM x AS INTEGER

    DIM y AS INTEGER

    stonenum(BLACKSIDE) = 0

    stonenum(WHITESIDE) = 0

    FOR x = 1 TO BOARDSIZE

        FOR y = 1 TO BOARDSIZE

            IF board(x, y) = BLACKSTONE THEN

                stonenum(BLACKSIDE) = stonenum(BLACKSIDE) + 1

            ELSEIF board(x, y) = WHITESTONE THEN

                stonenum(WHITESIDE) = stonenum(WHITESIDE) + 1

            END IF

        NEXT y

    NEXT x

    LOCATE 2, 8: PRINT USING nn; stonenum(BLACKSIDE);

    LOCATE 12, 8: PRINT USING nn; stonenum(WHITESIDE);

END SUB

SUB stoneshow (stone AS INTEGER, x AS INTEGER, y AS INTEGER)

    CALL othelloscreen(BOARDSCREEN, USE)

    IF stone = BLACKSTONE THEN

        CIRCLE (x - .5, y - .5), .4, BLACK

        PAINT (x - .5, y - .5), BLACK, BLACK

    ELSEIF stone = WHITESTONE THEN

        CIRCLE (x - .5, y - .5), .4, WHITE

        PAINT (x - .5, y - .5), WHITE, WHITE

    END IF

END SUB

SUB trapcontrol (control AS INTEGER) STATIC

    SHARED timetrap AS INTEGER

    SHARED keytrap AS INTEGER

    DIM n AS INTEGER

    DIM timetrapstack(1 TO 64) AS INTEGER

    DIM keytrapstack(1 TO 64) AS INTEGER


    IF control = TRAPINIT THEN

        FOR n = 1 TO 64

            timetrapstack(n) = EVENTOFF

            keytrapstack(n) = EVENTOFF

        NEXT n

        n = 0

    ELSEIF control = TRAPOFF THEN

        n = n + 1

        timetrapstack(n) = timetrap

        IF timetrap = EVENTON THEN

            TIMER STOP

            timetrap = EVENTSTOP

        END IF

        keytrapstack(n) = keytrap

        IF keytrap = EVENTON THEN

            KEY(10) STOP

            keytrap = EVENTSTOP

        END IF

    ELSEIF control = TRAPON THEN

        SELECT CASE timetrapstack(n)

            CASE EVENTOFF

                TIMER OFF

                timetrap = EVENTOFF

            CASE EVENTSTOP

                TIMER STOP

                timetrap = EVENTSTOP

            CASE EVENTON

                timetrap = EVENTON

                TIMER ON

        END SELECT

        SELECT CASE keytrapstack(n)

            CASE EVENTOFF

                KEY(10) OFF

                keytrap = EVENTOFF

            CASE EVENTSTOP

                KEY(10) STOP

                keytrap = EVENTSTOP

            CASE EVENTON

                keytrap = EVENTON

                KEY(10) ON

        END SELECT

        n = n - 1

    END IF

END SUB

SUB turnstone (board() AS INTEGER, x AS INTEGER, y AS INTEGER)

    DIM stone AS INTEGER

    DIM xplus AS INTEGER

    DIM yplus AS INTEGER

    DIM xpointer AS INTEGER

    DIM ypointer AS INTEGER

    DIM i AS INTEGER

    DIM j AS INTEGER

    stone = board(x, y)

    FOR xplus = -1 TO 1

        FOR yplus = -1 TO 1

            xpointer = x + xplus

            ypointer = y + yplus

            DO WHILE (xpointer >= 1 AND xpointer <= BOARDSIZE) AND (ypointer >= 1 AND ypointer <= BOARDSIZE)

                IF board(xpointer, ypointer) = stone THEN

                    i = x + xplus

                    j = y + yplus

                    DO UNTIL i = xpointer AND j = ypointer

                        board(i, j) = stone

                        CALL stoneshow(board(i, j), i, j)

                        i = i + xplus

                        j = j + yplus

                    LOOP

                    EXIT DO

                ELSEIF board(xpointer, ypointer) = BLANK THEN

                    EXIT DO

                END IF

                xpointer = xpointer + xplus

                ypointer = ypointer + yplus

            LOOP

        NEXT yplus

    NEXT xplus

END SUB

FUNCTION Verify$ (filenumber AS INTEGER, startadd AS LONG, endadd AS LONG)

    CONST TEMPSTRINGLEN = 8192

    DIM i AS INTEGER

    DIM p AS LONG

    DIM s AS LONG

    DIM l AS INTEGER

    DIM tempstring AS STRING

    DIM q AS INTEGER

    DIM t AS LONG

    DIM u AS DOUBLE

    DIM tc AS STRING * 2

    DIM verifyhex(0 TO 15) AS LONG

    DIM verifynum(0 TO 15) AS LONG

    DIM verifystring AS STRING

    tc = CHR$(0) + CHR$(0)

    FOR i = 0 TO 15

        verifyhex(i) = 0

        verifynum(i) = 0

    NEXT i

    p = startadd

    i = 0

    DO WHILE p <= endadd

        s = endadd - p + 1

        IF s < TEMPSTRINGLEN THEN

            l = s

        ELSE

            l = TEMPSTRINGLEN

        END IF

        tempstring = STRING$(l, 0)

        GET filenumber, p, tempstring

        IF l MOD 2 = 1 THEN

            l = l + 1

            tempstring = tempstring + CHR$(0)

        END IF

        FOR q = 1 TO l STEP 2

            t = CVL(MID$(tempstring, q, 2) + tc)

            verifyhex(15 - i) = verifyhex(15 - i) XOR t

            u = CDBL(t + 1) * FIX(65536 * RND + 1) + verifynum(i)

            verifynum(i) = u - FIX(u / 65536#) * 65536#

            i = (i + 1) MOD 16

        NEXT q

        p = p + l

    LOOP

    FOR i = 0 TO 15

        verifynum(i) = verifynum(i) XOR verifyhex(i)

    NEXT i

    verifystring = ""

    FOR i = 0 TO 15

        verifystring = verifystring + LEFT$(MKL$(verifynum(i)), 2)

    NEXT i

    Verify$ = verifystring

END FUNCTION

SUB winshow (winside AS INTEGER)

    IF winside = BLACKWIN THEN

        CALL faceshow(BLACKSIDE, WIN)

        CALL faceshow(WHITESIDE, LOSE)

    ELSEIF winside = WHITEWIN THEN

        CALL faceshow(BLACKSIDE, LOSE)

        CALL faceshow(WHITESIDE, WIN)

    ELSEIF winside = EQUAL THEN

        CALL faceshow(BLACKSIDE, QUIET)

        CALL faceshow(WHITESIDE, QUIET)

    END IF

END SUB

FUNCTION winsidejudge (nowside AS INTEGER, notime AS INTEGER, accpetlose AS INTEGER, stonenum() AS INTEGER)

    IF nowside = OVER THEN

        IF stonenum(BLACKSIDE) > stonenum(WHITESIDE) THEN

            winsidejudge = BLACKWIN

        ELSEIF stonenum(BLACKSIDE) = stonenum(WHITESIDE) THEN

            winsidejudge = EQUAL

        ELSEIF stonenum(BLACKSIDE) < stonenum(WHITESIDE) THEN

            winsidejudge = WHITEWIN

        END IF

    ELSEIF nowside <> OVER THEN

        IF notime = TRUE OR accpetlose = TRUE THEN

            IF nowside = BLACKSIDE THEN

                winsidejudge = BLACKWIN

            ELSEIF nowside = WHITESIDE THEN

                winsidejudge = WHITEWIN

            END IF

        END IF

    END IF

END FUNCTION

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章