인텔 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, DOSBox 또는 선호하는 에뮬레이터가있는 실제 IBM PC가 필요합니다.
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은 동일한 소스 / 대상을 사용합니다