[Fortran] 纯文本查看 复制代码
program main
use point24
use dislin
implicit none
integer,parameter::COUNT_OF_NUMBER=4 !4张牌
!牌的数值最大限制 4张牌数值 6个输入文本框
integer::Number_Scale=13,N(COUNT_OF_NUMBER),itxt(-1:COUNT_OF_NUMBER)
!不可编辑文本框编号itotal 计算按钮控件编号ical 主界面编号ip
integer::itotal,ical,ip
character(64)::temptext !临时变量
real::temp !随机数 单精度浮点数
integer::i
open(10,file="答案.txt") !打开输出文件
open(11,file="题目.txt") !打开输出文件
call random_seed() !随机种子
call swgwth(50) !正数为绝对宽度 负数为相对宽度
call swgfnt("Courier New",20) !Windows默认等宽字体
call swgopt('INTEGER', 'VERIFY') !enables a check of input characters in text and table cells. 限定文本框输入只能是整数 可以为负数
!DIGITS 0-9; INTEGER 0-9,'+','-'
call swgopt('OK','CLOSE') !将界面右上角关闭窗口设置为OK(退出界面,程序继续执行) 默认为Quit(退出程序)
call swgpop('NOQUIT') !Exit菜单无Quit子菜单 仅有OK子菜单 避免直接退出程序
call swgtit("24 Points(Author: Wei Xing)") !界面标题
call swghlp("Program For Calculating 24 Points|Author: Wei Xing|Email: [email]282844965@qq.com[/email]|Language: Fortran+Dislin11.5|Complier: SimplyFortran3.31") !帮助菜单显示信息
call wgini('VERT', ip) !界面初始化 垂直布局
!显示输入的最大限制值
call wgltxt(ip,"Maximum of Card:","13",30,itxt(-1)) !带标签的文本框 初值13
!显示运算目标值
call wgltxt(ip,"Target Number:","24",30,itxt(0)) !带标签的文本框 初值为24 可以设置为负整数
!显示每张牌
do i=1,COUNT_OF_NUMBER
write(temptext,"('No.',i0,' Card:')")i !标签
call wgltxt(ip,trim(temptext),"",30,itxt(i)) !带标签的文本框 初值为空字符
end do
call wgpbut(ip,"Calculate",ical) !按钮控件
call wgstxt(ip,2,99,itotal) !不可编辑文本框 2代表文本框显示高度占2行 99代表最多保存最近的99行 若超出则删除头部
call wgok(ip,i) !OK按钮控件 同Exit->OK 退出界面 程序继续运行wgfin之后代码
!第1次出题依次输入4张牌
call CardRandom() !随机出牌 Number_Scale为默认值13
!Number_Scale文本框数值改变后回车执行一次子程序change
call swgcbk(itxt(-1),change) !文本框驱动子程序
!单击一次Calculate按钮执行一次子程序calculate
call swgcbk(ical, calculate) !文本框驱动子程序
call wgfin !界面结束
write(10,*)"end" !文件结尾标志 Exit->OK能运行到这里 Exit->Quit和关闭窗口('Quit','CLOSE')均不能运行到这里
write(11,*)"end"
close(10) !关闭文件
close(11)
contains
subroutine calculate(id)
integer,intent(in)::id !已单击的按钮控件编号
integer::i,goal
integer,save::num=1 !静态变量 有解题目序号
character(64)::ans !题目答案
type(T_game24Point)::g24
call gwgint(itxt(-1),Number_Scale) !获取文本框输入整数 用户修改数据 限制牌的范围[1,Number_Scale]
if(Number_Scale<10)then
call msgbox("Warning:Maximum of Card must > 9.|Reset it within the correct range.") !弹出错误提示
call swgfoc(itxt(-1)) !键盘焦点放在出错的文本框上 便于用户重新输入
return !提前返回 等待用户重新输入 g24对象尚未分配内存
end if
write(ans,"(i0)")Number_Scale !整数转换为字符串
!牌的数据处理顺序为N(i)-->swgint-->文本框字符串(用户可更改)-->gwgint-->N(i)
!判断当前题目出牌数据是否在限定范围内[1,Number_Scale]
do i=1,COUNT_OF_NUMBER
!用户可手动更改文本框数值
call gwgint(itxt(i),N(i)) !获取文本框输入整数 用户修改数据 牌的数据
if(N(i)>Number_Scale .or. N(i)<1)then !输入范围限定
write(temptext,"(i0)")i !出错牌的序号
call msgbox("Warning:Input Integer must between [1,"//trim(ans)//"] in No."//trim(temptext)//" Card.|Reset it within the correct range.") !弹出错误提示 只会提示第1个错误
call swgfoc(itxt(i)) !键盘焦点放在出错的文本框上 便于用户重新输入
return !提前返回 等待用户重新输入 g24对象尚未分配内存
end if
end do
call gwgint(itxt(0),goal) !获取文本框输入整数 用户修改数据 运算目标值Targer Number
call g24%setNum(N,goal) !对象初始化 分配内存
write(ans,"(i0)")num !整数转换为字符串 题目序号
write(temptext,"(i0)")g24%getGoal() !整数转换为字符串 运算目标值
!当前题目计算答案
If(g24%Search())Then !有解
write(11,*)"No."//trim(ans)//" Question:(Target->"//trim(temptext)//")" !题目文件输出题目编号
write(11,*)" "//g24%getCard() !题目文件输出题目内容 剔除无解题目
ans="No."//trim(ans)//" Answer:"//trim(temptext)//"="//g24%getExpression() !屏幕显示答案
write(10,*)ans !答案文件输出结果 剔除无解题目
num=num+1 !有解的情况下题目序号才递增
Else !无解
ans="No."//trim(ans)//" Answer:None("//trim(temptext)//"/="//g24%getCard()//")" !屏幕显示无解
End If
!更新下一题出牌
call CardRandom() !随机出牌
!更新当前题目答案
call swgtxt(itotal, trim(ans)) !文本框改变显示答案 wgstxt不是覆盖而是尾部另起一行增加
call g24%free() !释放对象内存
end subroutine calculate
!牌的最大值文本框中重新设置数值Number_Scale后按回车 相应更新随机出牌
subroutine change(id)
integer,intent(in)::id !数据改变的文本框编号
call gwgint(itxt(-1),Number_Scale) !获取文本框输入整数 用户修改数据 限制牌的范围[1,Number_Scale]
if(Number_Scale<10)then
call msgbox("Warning:Maximum of Card must > 9.|Reset it within the correct range.") !弹出错误提示
call swgfoc(itxt(-1)) !键盘焦点放在出错的文本框上 便于用户重新输入
return !提前返回 等待用户重新输入 g24对象尚未分配内存
end if
call CardRandom() !随机出牌
end subroutine change
!随机出牌并在文本框显示 共3处调用:1主程序第1次出牌、2calculate子程序、3change子程序
subroutine CardRandom()
integer::i
do i=1,COUNT_OF_NUMBER
call random_number(temp) !生成随机数[0,1) 单精度浮点数
N(i)=int(temp*Number_Scale)+1 !下一题随机出牌[1,Number_Scale]
!对象初始化发生在单击Calculate按钮后 没有必要在这里确定
call swgint(itxt(i), N(i)) !文本框更新显示整数 程序修改数据 牌的数值
end do
end subroutine CardRandom
end program