Intel 8086/8087アセンブリ、 180 144 142 138バイト
これは、すべてのトリガーおよび浮動小数点演算に8087数学コプロセッサーを使用します。すべての計算は、80ビット浮動小数点精度のハードウェアで行われます。
df06 b101 d8c8 df06 af01 d8c8 dec1 d9fa df1e b301 8b16 b301
33c0 81fa aa00 7c03 eb53 9083 fa06 7d05 b032 eb49 9083 fa10
7d05 b019 eb3f 90df 06b7 01df 06b5 01d9 f3df 06b1 01dd d2d9
ebde f9de c9de c1df 1eb3 01a1 b301 bb9c 01d7 83fa 6b7d 0a83
fa63 7c05 b303 eb09 9081 faa2 007c 04b3 02f6 e30b 0810 0713
0311 020f 0a06 0d04 1201 1405 0c09 0e0b 0a00
MASM MACRO(基本的に関数)として記述され、XとYを座標として取り、AXで計算されたスコアを返します。タイは時計回りに壊れています。
MAX_BULL EQU 6
MAX_25 EQU 16
MIN_3X EQU 99
MAX_3X EQU 107
MIN_2X EQU 162
MAX_2X EQU 170
; cartesian coordinates to radius
; ST = sqrt( X^2 + Y^2 )
; input: X,Y (mem16,mem16)
; output: Radius (mem16)
FCRAD MACRO X, Y, R
FILD Y ; ST[] = Y
FMUL ST,ST ; ST = y^2
FILD X ; ST[] = X
FMUL ST,ST ; ST = x^2
FADD ; ST = ST + ST1
FSQRT ; ST = SQRT(ST)
FISTP R ; R = ROUND(ST)
ENDM
; cartesian coordinates to sector #
; input: X,Y (mem16,mem16)
; output: Sector (mem16)
FCSEC MACRO X, Y, S
FILD Y ; ST[] = Y
FILD X ; ST[] = X
FPATAN ; ST = atan2(Y,X)
FILD CTEN ; ST[] = 10
FST ST(2) ; ST(2) = 10
FLDPI ; ST[] = pi
FDIV ; ST = 10 / pi
FMUL ; ST = A * ST
FADD ; ST = ST + 10
FISTP S ; S = ROUND(ST)
ENDM
; score the dart throw
; input: X / Y coordinates (mem16)
; output: Score (AX)
SCORE MACRO X, Y
LOCAL IS_BULL, IS_25, IS_3X, IS_2X, MUL_SCORE, DONE
FCRAD X, Y, FDW ; FDW = radius(X,Y)
MOV DX, FDW ; DX = FDW = radius
XOR AX, AX ; score is initially 0
CMP DX, MAX_2X ; >= 170 (miss)
JL IS_BULL ; if not, check for bullseye
JMP DONE
IS_BULL:
CMP DX, MAX_BULL ; < 6 (inner bullseye)
JGE IS_25 ; if not, check for 25
MOV AL, 50 ; score is 50
JMP DONE
IS_25:
CMP DX, MAX_25 ; < 16 (outer bullseye)
JGE IS_3X ; if not, check for triple
MOV AL, 25 ; score is 25
JMP DONE
IS_3X:
FCSEC X, Y, FDW ; FDW = sector(X,Y)
MOV AX, FDW ; load sector # into AX
MOV BX, OFFSET SCR ; load base score table
XLAT ; put base score into AL
CMP DX, MAX_3X ; < 107 (triple upper bounds)
JGE IS_2X ; if not, check for double
CMP DX, MIN_3X ; >= 99 (triple lower bounds)
JL IS_2X ; if not, check for double
MOV BL, 3 ; this is triple score
JMP MUL_SCORE ; go forth and multiply
IS_2X:
CMP DX, MIN_2X ; >= 162 (double lower bounds) (> 170 already checked)
JL DONE ; if not, single score
MOV BL, 2 ; this is double score
MUL_SCORE:
MUL BL ; multiply score either 2x or 3x
DONE:
ENDM
; DATA (place in appropriate segment)
SCR DB 11,8,16,7,19,3,17,2,15,10,6 ; score table
DB 13,4,18,1,20,5,12,9,14,11
CTEN DW 10 ; constant 10 to load into FPU
FDW DW ? ; temp DW variable for CPU/FPU data transfer
PC DOS用のサンプルテストプログラム。DARTTEST.COMからダウンロードしてください。
INCLUDE DART.ASM ; the above file
INCLUDE INDEC.ASM ; generic I/O routines - input int
INCLUDE OUTDEC.ASM ; generic I/O routines - output int
FINIT ; reset 8087
MOV AH, 2 ; display "X" prompt
MOV DL, 'X'
INT 21H
CALL INDEC ; read decimal for X into AX
MOV X, AX
MOV AH, 2 ; display "Y" prompt
MOV DL, 'Y'
INT 21H
CALL INDEC ; read decimal for Y into AX
MOV Y, AX
SCORE X, Y ; AX = SCORE( X, Y )
CALL OUTDEC ; display score
X DW ?
Y DW ?
出力
上記のテストプログラムの使用例。8087を搭載した実際のIBM PC、DOSBox、またはお気に入りのエミュレーターが必要です。
A>DARTTEST.COM
X: 0
Y: 0
50
A>DARTTEST.COM
X: 2
Y: 101
60
A>DARTTEST.COM
X: -163
Y: -1
22
A>DARTTEST.COM
X: 6
Y: 18
1
A>DARTTEST.COM
X: -6
Y: 18
5
A>DARTTEST.COM
X: 45
Y: -169
0
A>DARTTEST.COM
X: 22
Y: 22
4
A>DARTTEST.COM
X: -150
Y: 0
11
A>DARTTEST.COM
X: -150
Y: 0
11
A>DARTTEST.COM
X: -150
Y: -1
11
A>DARTTEST.COM
X: -7
Y: -6
25
A>DARTTEST.COM
X: -90
Y: 138
24
*編集:
- 切り捨て丸めステートメントと10.5定数を削除して-36バイト。タイは時計回りに壊れています。
- 不要なFRNDINTを削除して-2バイト
- -4バイト、FMULは同じソース/宛先を使用