32位汇编八皇后问题

回溯法解决八皇后问题
八皇后问题是以国际象棋为背景的问题:有八个皇后(可以当成八个棋子),如何在 8*8 的棋盘中放置八个皇后,
使得任意两个皇后都不在同一条横线、纵线或者斜线上。
八皇后问题是使用回溯法解决的典型案例。算法的解决思路是:
1.从棋盘的第一行开始,从第一个位置开始,依次判断当前位置是否能够放置皇后,判断的依据为:
  同该行之前的所有行中皇后的所在位置进行比较,如果在同一列,或者在同一条斜线上
  (斜线有两条,为正方形的两个对角线),都不符合要求,继续检验后序的位置。
2.如果该行所有位置都不符合要求,则回溯到前一行,改变皇后的位置,继续试探。
3.如果试探到最后一行,所有皇后摆放完毕,则直接打印出 8*8 的棋盘。最后一定要记得将棋盘恢复原样,避免影响下一次摆放。

#include <stdio.h>
int Queenes[8]={0},Counts=0;
int Check(int line,int list){
    //遍历该行之前的所有行
    for (int index=0; index<line; index++) {
        //挨个取出前面行中皇后所在位置的列坐标
        int data=Queenes[index];
        //如果在同一列,该位置不能放
        if (list==data) {
            return 0;
        }
        //如果当前位置的斜上方有皇后,在一条斜线上,也不行
        if ((index+data)==(line+list)) {
            return 0;
        }
        //如果当前位置的斜下方有皇后,在一条斜线上,也不行
        if ((index-data)==(line-list)) {
            return 0;
        }
    }
    //如果以上情况都不是,当前位置就可以放皇后
    return 1;
}
//输出语句
void print()
{
    for (int line = 0; line < 8; line++)
    {
        int list;
        for (list = 0; list < Queenes[line]; list++)
            printf("0");
        printf("#");
        for (list = Queenes[line] + 1; list < 8; list++){
            printf("0");
        }
        printf("\n");
    }
    printf("================\n");
}

void eight_queen(int line){
    //在数组中为0-7列
    for (int list=0; list<8; list++) {
        //对于固定的行列,检查是否和之前的皇后位置冲突
        if (Check(line, list)) {
            //不冲突,以行为下标的数组位置记录列数
            Queenes[line]=list;
            //如果最后一样也不冲突,证明为一个正确的摆法
            if (line==7) {
                //统计摆法的Counts加1
                Counts++;
                //输出这个摆法
                print();
                //每次成功,都要将数组重归为0
                Queenes[line]=0;
                return;
            }
            //继续判断下一样皇后的摆法,递归
            eight_queen(line+1);
            //不管成功失败,该位置都要重新归0,以便重复使用。
            Queenes[line]=0;
        }
    }
}
int main() {
    //调用回溯函数,参数0表示从棋盘的第一行开始判断
    eight_queen(0);
    printf("摆放的方式有%d种",Counts);
    return 0;
}

汇编代码

INCLUDE Irvine32.inc
.data
    Queens dd 8 dup(0)
    Count dd 0
    msg db 'The number of the way setting is:',0
    sep db '===============',0
    eight dd 8
    seven dd 7
.code
main PROC
    mov eax,0
    push eax
    call eight_queen

    lea edx,msg
    call writestring
    mov eax,Count
    call writedec
    call crlf
    ; call print
    exit
main ENDP

eight_queen PROC
    push ebp
    mov ebp,esp
    pushad
    mov esi,[ebp+8]     ;esi:line
    mov edi,0           ;edi:list

    ; mov eax,esi
    ; call writedec
    ; call crlf

for_0:
    cmp edi,eight
    jge final
    push edi
    push esi
    call Check


    cmp eax,1
    jne for_0_end
    mov edx,offset Queens   ;edx:Queens
    mov [edx+esi*4],edi
    cmp esi,seven

    ; mov eax,edi
    ; call writedec
    ; call crlf

    jne next
    inc Count
    call print
    mov eax,0
    mov edx,offset Queens 
    mov [edx+esi*4],eax
    jmp final
next:
    mov eax,esi
    add eax,1
    push eax
    call eight_queen

    mov edx,offset Queens
    mov eax,0
    mov [edx+esi*4],eax
for_0_end:
    inc edi
    jmp for_0
final:
    popad
    pop ebp
    ret 4
eight_queen ENDP

Check PROC
    push ebp
    mov ebp,esp
    sub esp,4
    pushad
    mov ecx,[ebp+8]     ;ecx:line
    mov edx,[ebp+12]    ;edx:list
    mov esi,0           ;esi:index
for_0:
    cmp esi,ecx
    jge ret1
    mov ebx,offset Queens   ;ebx:Queens
    mov edi,[ebx+esi*4]     ;edi:data
    cmp edx,edi
    je ret0

    ; mov ebx,offset Queens 
    mov edi,esi
    add edi,[ebx+esi*4]
    sub edi,ecx
    sub edi,edx
    cmp edi,0
    je ret0

    ; mov ebx,offset Queens 
    mov edi,esi
    sub edi,[ebx+esi*4]
    sub edi,ecx
    add edi,edx
    cmp edi,0
    je ret0
for_0_end:
    inc esi
    jmp for_0
ret1:
    mov eax,1
    mov [ebp-4],eax
    jmp final
ret0:
    mov eax,0
    mov [ebp-4],eax
    jmp final
final:     
    popad
    mov eax,[ebp-4]
    add esp,4
    pop ebp
    ret 8
Check ENDP

print PROC
    push ebp
    mov ebp,esp
    pushad
    mov esi,0       ;esi:line
for_0:
    cmp esi,eight
    jge final
    mov edi,0       ;edi:list
for_1:
    mov edx,offset Queens   ;edx:Queens
    cmp edi,[edx+esi*4]
    jge next
    mov eax,0
    call writedec
for_1_end:
    inc edi
    jmp for_1
next:
    mov al,'#'
    call writechar
    mov edx,offset Queens   ;edx:Queens
    mov edi,[edx+esi*4]
    inc edi
for_2:
    cmp edi,eight
    jge for_0_end
    mov eax,0
    call writedec
for_2_end:
    inc edi
    jmp for_2
for_0_end:
    call crlf
    inc esi
    jmp for_0
final:
    lea edx,sep
    call writestring
    call crlf
    popad
    pop ebp
    ret
print ENDP
END main

  • 6
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值