├── .github └── FUNDING.yml ├── .gitignore ├── LICENSE ├── LUATeach.sln ├── LUATeach ├── 1-svg.ico ├── App.config ├── App.xaml ├── App.xaml.cs ├── Assets │ ├── picture │ │ ├── lua.png │ │ ├── luac.png │ │ └── luat.png │ └── script │ │ ├── JSON.lua │ │ ├── head.lua │ │ ├── levels │ │ ├── break.lua │ │ ├── for.lua │ │ ├── function_return.lua │ │ ├── function_return2.lua │ │ ├── function_return3.lua │ │ ├── loop1.lua │ │ ├── loop2.lua │ │ ├── loop3.lua │ │ ├── loop4.lua │ │ ├── string.byte.lua │ │ ├── string.char.lua │ │ ├── string.find.lua │ │ ├── string.format.lua │ │ ├── string.gsub.lua │ │ ├── string.len.lua │ │ ├── string.low.lua │ │ ├── string.lua │ │ ├── string.rep.lua │ │ ├── string.sub.lua │ │ ├── table.concat.lua │ │ ├── table.insert.lua │ │ ├── table1.lua │ │ ├── table2.lua │ │ ├── table3.lua │ │ ├── table4.lua │ │ ├── table5.lua │ │ ├── table6.lua │ │ └── while.lua │ │ ├── log.lua │ │ ├── strings.lua │ │ └── sys.lua ├── FodyWeavers.xml ├── FodyWeavers.xsd ├── Global │ ├── Levels.cs │ ├── Settings.cs │ └── Utils.cs ├── Images │ ├── clock_go.png │ ├── clock_go_32.png │ ├── clock_play.png │ ├── download.png │ ├── download_32.png │ ├── hand_point.png │ ├── icon.ico │ └── update.png ├── LUATeach.csproj ├── Lib │ └── XLua.Mini.dll ├── Lua.xshd ├── LuaEnv │ ├── LuaApi.cs │ ├── LuaEnv.cs │ └── LuaRunEnv.cs ├── MainWindow.xaml ├── MainWindow.xaml.cs ├── Pages │ ├── CodingPage.xaml │ ├── CodingPage.xaml.cs │ ├── HomePage.xaml │ ├── HomePage.xaml.cs │ ├── IntroducePage.xaml │ ├── IntroducePage.xaml.cs │ ├── LuaEditorPage.xaml │ ├── LuaEditorPage.xaml.cs │ ├── LuaListPage.xaml │ ├── LuaListPage.xaml.cs │ ├── RightPage.xaml │ └── RightPage.xaml.cs ├── Properties │ ├── AssemblyInfo.cs │ ├── Resources.Designer.cs │ ├── Resources.resx │ ├── Settings.Designer.cs │ └── Settings.settings ├── costura32 │ └── xlua.dll └── packages.config ├── README.md ├── changlog ├── autoUpdate.xml └── index.html ├── screen1.jpg └── screen2.jpg /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: chenxuuu 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.suo 8 | *.user 9 | *.userosscache 10 | *.sln.docstates 11 | 12 | # User-specific files (MonoDevelop/Xamarin Studio) 13 | *.userprefs 14 | 15 | # Build results 16 | [Dd]ebug/ 17 | [Dd]ebugPublic/ 18 | [Rr]elease/ 19 | [Rr]eleases/ 20 | x64/ 21 | x86/ 22 | bld/ 23 | [Bb]in/ 24 | [Oo]bj/ 25 | [Ll]og/ 26 | 27 | # Visual Studio 2015/2017 cache/options directory 28 | .vs/ 29 | # Uncomment if you have tasks that create the project's static files in wwwroot 30 | #wwwroot/ 31 | 32 | # Visual Studio 2017 auto generated files 33 | Generated\ Files/ 34 | 35 | # MSTest test Results 36 | [Tt]est[Rr]esult*/ 37 | [Bb]uild[Ll]og.* 38 | 39 | # NUNIT 40 | *.VisualState.xml 41 | TestResult.xml 42 | 43 | # Build Results of an ATL Project 44 | [Dd]ebugPS/ 45 | [Rr]eleasePS/ 46 | dlldata.c 47 | 48 | # Benchmark Results 49 | BenchmarkDotNet.Artifacts/ 50 | 51 | # .NET Core 52 | project.lock.json 53 | project.fragment.lock.json 54 | artifacts/ 55 | **/Properties/launchSettings.json 56 | 57 | # StyleCop 58 | StyleCopReport.xml 59 | 60 | # Files built by Visual Studio 61 | *_i.c 62 | *_p.c 63 | *_i.h 64 | *.ilk 65 | *.meta 66 | *.obj 67 | *.iobj 68 | *.pch 69 | *.pdb 70 | *.ipdb 71 | *.pgc 72 | *.pgd 73 | *.rsp 74 | *.sbr 75 | *.tlb 76 | *.tli 77 | *.tlh 78 | *.tmp 79 | *.tmp_proj 80 | *.log 81 | *.vspscc 82 | *.vssscc 83 | .builds 84 | *.pidb 85 | *.svclog 86 | *.scc 87 | 88 | # Chutzpah Test files 89 | _Chutzpah* 90 | 91 | # Visual C++ cache files 92 | ipch/ 93 | *.aps 94 | *.ncb 95 | *.opendb 96 | *.opensdf 97 | *.sdf 98 | *.cachefile 99 | *.VC.db 100 | *.VC.VC.opendb 101 | 102 | # Visual Studio profiler 103 | *.psess 104 | *.vsp 105 | *.vspx 106 | *.sap 107 | 108 | # Visual Studio Trace Files 109 | *.e2e 110 | 111 | # TFS 2012 Local Workspace 112 | $tf/ 113 | 114 | # Guidance Automation Toolkit 115 | *.gpState 116 | 117 | # ReSharper is a .NET coding add-in 118 | _ReSharper*/ 119 | *.[Rr]e[Ss]harper 120 | *.DotSettings.user 121 | 122 | # JustCode is a .NET coding add-in 123 | .JustCode 124 | 125 | # TeamCity is a build add-in 126 | _TeamCity* 127 | 128 | # DotCover is a Code Coverage Tool 129 | *.dotCover 130 | 131 | # AxoCover is a Code Coverage Tool 132 | .axoCover/* 133 | !.axoCover/settings.json 134 | 135 | # Visual Studio code coverage results 136 | *.coverage 137 | *.coveragexml 138 | 139 | # NCrunch 140 | _NCrunch_* 141 | .*crunch*.local.xml 142 | nCrunchTemp_* 143 | 144 | # MightyMoose 145 | *.mm.* 146 | AutoTest.Net/ 147 | 148 | # Web workbench (sass) 149 | .sass-cache/ 150 | 151 | # Installshield output folder 152 | [Ee]xpress/ 153 | 154 | # DocProject is a documentation generator add-in 155 | DocProject/buildhelp/ 156 | DocProject/Help/*.HxT 157 | DocProject/Help/*.HxC 158 | DocProject/Help/*.hhc 159 | DocProject/Help/*.hhk 160 | DocProject/Help/*.hhp 161 | DocProject/Help/Html2 162 | DocProject/Help/html 163 | 164 | # Click-Once directory 165 | publish/ 166 | 167 | # Publish Web Output 168 | *.[Pp]ublish.xml 169 | *.azurePubxml 170 | # Note: Comment the next line if you want to checkin your web deploy settings, 171 | # but database connection strings (with potential passwords) will be unencrypted 172 | *.pubxml 173 | *.publishproj 174 | 175 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 176 | # checkin your Azure Web App publish settings, but sensitive information contained 177 | # in these scripts will be unencrypted 178 | PublishScripts/ 179 | 180 | # NuGet Packages 181 | *.nupkg 182 | # The packages folder can be ignored because of Package Restore 183 | **/[Pp]ackages/* 184 | # except build/, which is used as an MSBuild target. 185 | !**/[Pp]ackages/build/ 186 | # Uncomment if necessary however generally it will be regenerated when needed 187 | #!**/[Pp]ackages/repositories.config 188 | # NuGet v3's project.json files produces more ignorable files 189 | *.nuget.props 190 | *.nuget.targets 191 | 192 | # Microsoft Azure Build Output 193 | csx/ 194 | *.build.csdef 195 | 196 | # Microsoft Azure Emulator 197 | ecf/ 198 | rcf/ 199 | 200 | # Windows Store app package directories and files 201 | AppPackages/ 202 | BundleArtifacts/ 203 | Package.StoreAssociation.xml 204 | _pkginfo.txt 205 | *.appx 206 | 207 | # Visual Studio cache files 208 | # files ending in .cache can be ignored 209 | *.[Cc]ache 210 | # but keep track of directories ending in .cache 211 | !*.[Cc]ache/ 212 | 213 | # Others 214 | ClientBin/ 215 | ~$* 216 | *~ 217 | *.dbmdl 218 | *.dbproj.schemaview 219 | *.jfm 220 | *.pfx 221 | *.publishsettings 222 | orleans.codegen.cs 223 | 224 | # Including strong name files can present a security risk 225 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 226 | #*.snk 227 | 228 | # Since there are multiple workflows, uncomment next line to ignore bower_components 229 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 230 | #bower_components/ 231 | 232 | # RIA/Silverlight projects 233 | Generated_Code/ 234 | 235 | # Backup & report files from converting an old project file 236 | # to a newer Visual Studio version. Backup files are not needed, 237 | # because we have git ;-) 238 | _UpgradeReport_Files/ 239 | Backup*/ 240 | UpgradeLog*.XML 241 | UpgradeLog*.htm 242 | ServiceFabricBackup/ 243 | *.rptproj.bak 244 | 245 | # SQL Server files 246 | *.mdf 247 | *.ldf 248 | *.ndf 249 | 250 | # Business Intelligence projects 251 | *.rdl.data 252 | *.bim.layout 253 | *.bim_*.settings 254 | *.rptproj.rsuser 255 | 256 | # Microsoft Fakes 257 | FakesAssemblies/ 258 | 259 | # GhostDoc plugin setting file 260 | *.GhostDoc.xml 261 | 262 | # Node.js Tools for Visual Studio 263 | .ntvs_analysis.dat 264 | node_modules/ 265 | 266 | # Visual Studio 6 build log 267 | *.plg 268 | 269 | # Visual Studio 6 workspace options file 270 | *.opt 271 | 272 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 273 | *.vbw 274 | 275 | # Visual Studio LightSwitch build output 276 | **/*.HTMLClient/GeneratedArtifacts 277 | **/*.DesktopClient/GeneratedArtifacts 278 | **/*.DesktopClient/ModelManifest.xml 279 | **/*.Server/GeneratedArtifacts 280 | **/*.Server/ModelManifest.xml 281 | _Pvt_Extensions 282 | 283 | # Paket dependency manager 284 | .paket/paket.exe 285 | paket-files/ 286 | 287 | # FAKE - F# Make 288 | .fake/ 289 | 290 | # JetBrains Rider 291 | .idea/ 292 | *.sln.iml 293 | 294 | # CodeRush 295 | .cr/ 296 | 297 | # Python Tools for Visual Studio (PTVS) 298 | __pycache__/ 299 | *.pyc 300 | 301 | # Cake - Uncomment if you are using it 302 | # tools/** 303 | # !tools/packages.config 304 | 305 | # Tabs Studio 306 | *.tss 307 | 308 | # Telerik's JustMock configuration file 309 | *.jmconfig 310 | 311 | # BizTalk build output 312 | *.btp.cs 313 | *.btm.cs 314 | *.odx.cs 315 | *.xsd.cs 316 | 317 | # OpenCover UI analysis results 318 | OpenCover/ 319 | 320 | # Azure Stream Analytics local run output 321 | ASALocalRun/ 322 | 323 | # MSBuild Binary and Structured Log 324 | *.binlog 325 | 326 | # NVidia Nsight GPU debugger configuration file 327 | *.nvuser 328 | 329 | # MFractors (Xamarin productivity tool) working folder 330 | .mfractor/ 331 | -------------------------------------------------------------------------------- /LUATeach.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.29123.88 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LUATeach", "LUATeach\LUATeach.csproj", "{7483AAE5-523C-4F92-94C4-759C49EAF7B6}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {7483AAE5-523C-4F92-94C4-759C49EAF7B6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {7483AAE5-523C-4F92-94C4-759C49EAF7B6}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {7483AAE5-523C-4F92-94C4-759C49EAF7B6}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {7483AAE5-523C-4F92-94C4-759C49EAF7B6}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {B5C36777-DA75-4CB8-A6AD-E955247CF580} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /LUATeach/1-svg.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxuuu/LUATeach/c975b210b88e10b50c6a590472b9d6380befd649/LUATeach/1-svg.ico -------------------------------------------------------------------------------- /LUATeach/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 |
6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | --此处可测试你的lua脚本运行效果 15 | --支持Lua5.3自带功能、以及LUAT Task任务相关接口 16 | --同时支持XLua直接调用C#接口的功能 17 | 18 | --新建任务,每休眠1000ms继续一次 19 | sys.taskInit(function() 20 | while true do 21 | sys.wait(1000)--等待1000ms 22 | log.info("task wait",os.time()) 23 | end 24 | end) 25 | 26 | --1000ms循环定时器 27 | sys.timerLoopStart(log.info,1000,"timer test") 28 | 29 | 30 | 31 | 32 | 0 33 | 34 | 35 | True 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /LUATeach/App.xaml: -------------------------------------------------------------------------------- 1 |  7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /LUATeach/App.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Configuration; 4 | using System.Data; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | using System.Windows; 8 | 9 | namespace LUATeach 10 | { 11 | /// 12 | /// App.xaml 的交互逻辑 13 | /// 14 | public partial class App : Application 15 | { 16 | 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /LUATeach/Assets/picture/lua.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxuuu/LUATeach/c975b210b88e10b50c6a590472b9d6380befd649/LUATeach/Assets/picture/lua.png -------------------------------------------------------------------------------- /LUATeach/Assets/picture/luac.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxuuu/LUATeach/c975b210b88e10b50c6a590472b9d6380befd649/LUATeach/Assets/picture/luac.png -------------------------------------------------------------------------------- /LUATeach/Assets/picture/luat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxuuu/LUATeach/c975b210b88e10b50c6a590472b9d6380befd649/LUATeach/Assets/picture/luat.png -------------------------------------------------------------------------------- /LUATeach/Assets/script/head.lua: -------------------------------------------------------------------------------- 1 | --提前运行的脚本 2 | --用于提前声明某些要用到的函数 3 | 4 | --加强随机数随机性 5 | math.randomseed(tostring(os.time()):reverse():sub(1, 6)) 6 | 7 | --防止跑死循环,超时设置秒数自动结束,-1表示禁用 8 | local runMaxSeconds = 5 9 | local start = os.time() 10 | local runCount = 0 11 | function trace (event, line) 12 | if runMaxSeconds > 0 then 13 | runCount = runCount + 1 14 | if runCount > 100000 then 15 | error("too many codes!") 16 | end 17 | end 18 | if runMaxSeconds > 0 and os.time() - start >=runMaxSeconds then 19 | error("code run timeout") 20 | end 21 | end 22 | debug.sethook(trace, "l") 23 | function setRunMaxSeconds(n) 24 | runMaxSeconds = n 25 | end 26 | 27 | --加上需要require的路径 28 | local rootPath = apiUtf8ToHex(apiGetPath()) 29 | rootPath = rootPath:gsub("[%s%p]", ""):upper() 30 | rootPath = rootPath:gsub("%x%x", function(c) 31 | return string.char(tonumber(c, 16)) 32 | end) 33 | package.path = package.path.. 34 | ";"..rootPath.."?.lua".. 35 | ";"..rootPath.."require/?.lua".. 36 | ";"..rootPath.."requires/?.lua" 37 | 38 | --重载几个可能影响中文目录的函数 39 | local oldrequire = require 40 | require = function (s) 41 | local s = apiUtf8ToHex(s):fromHex() 42 | return oldrequire(s) 43 | end 44 | local oldloadfile = loadfile 45 | loadfile = function (s) 46 | local s = apiUtf8ToHex(s):fromHex() 47 | return oldloadfile(s) 48 | end 49 | local oldioopen = io.open 50 | io.open = function (s,p) 51 | local s = apiUtf8ToHex(s):fromHex() 52 | return oldioopen(s,p) 53 | end 54 | 55 | --重写print函数 56 | function print(...) 57 | arg = { ... } 58 | if #arg == 0 then apiPrintLog("nil") return end 59 | local logAll = {} 60 | for i=1,select('#', ...) do 61 | table.insert(logAll, tostring(arg[i])) 62 | end 63 | apiPrintLog(table.concat(logAll, "\t")) 64 | end 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /LUATeach/Assets/script/levels/break.lua: -------------------------------------------------------------------------------- 1 | 2 | title = "break" 3 | type = "写代码" 4 | infomation = "学习break语句" 5 | question = [[前面我们学习了循环语句,有些时候循环运行到一半,我们不想再继续运行了,怎么办呢? 6 | 7 | 我们可以在一个循环体中使用`break`,来立即结束本次循环,继续运行下面的代码 8 | 9 | 比如像下面这样,计算1-100相加途中,小于100的最大的和: 10 | 11 | ```lua 12 | result = 0 13 | for i=1,100 do 14 | result = result + i 15 | if result > 100 then 16 | result = result - i 17 | break 18 | end 19 | end 20 | 21 | print(result) 22 | ``` 23 | 24 | 可以看见,当发现和大于100后,代码立即把`result`的值还原到了加上当前数字之前的状态,并且调用`break`语句,立即退出了本次循环 25 | 26 | 实际上,在`while`中,我们也可以使用`break`: 27 | 28 | ```lua 29 | result = 0 30 | c = 1 31 | while true do 32 | result = result + c 33 | c = c + 1 34 | if result > 100 then 35 | result = result - i 36 | break 37 | end 38 | end 39 | 40 | print(result) 41 | ``` 42 | 43 | 我们在这里直接使用了死循环(因为`while`的继续运行判断依据始终为`true`),整体逻辑也和之前for的代码一致,当发现和大于100后,代码立即把`result`的值还原到了加上当前数字之前的状态,并且调用`break`语句,立即退出了本次循环 44 | 45 | 现在你需要完成一项任务: 46 | 47 | 请求出大于变量`max`的,最小的`13的倍数` 48 | 49 | 并将结果放置于新建的变量`result`中 50 | 51 | (`max`大于0) 52 | ]] 53 | code = [[ 54 | --请补全代码 55 | result = 0 56 | for 57 | ]] 58 | explain = "至此,你已经初步掌握了循环语句" 59 | 60 | check = function(s) 61 | 62 | if not s:find("for") and not s:find("while") then 63 | return "请使用循环语句来解决该问题" 64 | end 65 | 66 | local lua = CS.LUATeach.LuaEnv.LuaEnv.CreateLuaEnv() 67 | local ran2 = math.random(500,2000) 68 | local r,i = pcall(function () 69 | lua:DoString("max="..tostring(ran2)) 70 | lua:DoString(s) 71 | lua:DoString("max="..tostring(ran2)) 72 | local lr = lua:DoString([[ 73 | check = 0 74 | for i=max,max+13 do 75 | if i%13==0 then 76 | check=i 77 | break 78 | end 79 | end 80 | return result == check 81 | ]]) 82 | return lr and lr[0] 83 | end) 84 | if r then 85 | if not i then 86 | local lr = lua:DoString("return result")[0] 87 | local lc = lua:DoString("return check")[0] 88 | lua:Dispose()--销毁对象释放资源 89 | return "和不符合要求哦,当max为"..tostring(ran2).."时符合要求的数应为"..tostring(lc).."\r\n".. 90 | "但是你的结果为"..tostring(lr) 91 | end 92 | else 93 | lua:Dispose()--销毁对象释放资源 94 | return "代码报错啦,请检查是否有语法错误或运行时错误\r\n报错信息:\r\n".. 95 | (i:match("c# exception:XLua.LuaException: (.-)\r\n") or i) 96 | end 97 | lua:Dispose()--销毁对象释放资源 98 | return "" 99 | end 100 | -------------------------------------------------------------------------------- /LUATeach/Assets/script/levels/for.lua: -------------------------------------------------------------------------------- 1 | 2 | title = "for循环" 3 | type = "写代码" 4 | infomation = "学习for循环语句" 5 | question = [[for循环在某些程度上,和while循环很相似,但是for循环可以更加简洁地表达中间累积的量 6 | 7 | 我们首先来学习`for`这个循环语法,整体的格式如下: 8 | 9 | ```lua 10 | for 临时变量名=开始值,结束值,步长 do 11 | 循环的代码 12 | end 13 | ``` 14 | 15 | 其中,`步长`可以省略,默认为1 16 | 17 | `临时变量名`可以直接在代码区域使用,每次循环会自动加`步长值`,并且在到达`结束值`后停止循环 18 | 19 | 下面举一个例子,我们计算从1加到100的结果: 20 | 21 | ``` 22 | local result = 0 23 | 24 | for i=1,100 do 25 | result = result + i 26 | end 27 | 28 | print(result) 29 | ``` 30 | 31 | 上面的代码,就是当i≤100时,result不断地加i,并且i每次循环后增加1 32 | 33 | 理解了上面的代码,我们来完成下面一个简单的任务吧: 34 | 35 | 已知两个number类型的变量`min`和`max` 36 | 37 | 请计算从`min`与`max`之间,所有`7的倍数`的`和` 38 | 39 | 新建一个变量`result`,将结果存到这个变量中 40 | ]] 41 | code = [[ 42 | --请补全代码 43 | result = 0 44 | for 45 | ]] 46 | explain = "repeat这个不会进行介绍,和while语法重复度太高了" 47 | 48 | check = function(s) 49 | local lua = CS.LUATeach.LuaEnv.LuaEnv.CreateLuaEnv() 50 | local ran1 = math.random(1,100) 51 | local ran2 = math.random(500,1000) 52 | local r,i = pcall(function () 53 | lua:DoString("min="..tostring(ran1).."\r\nmax="..tostring(ran2)) 54 | lua:DoString(s) 55 | lua:DoString("min="..tostring(ran1).."\r\nmax="..tostring(ran2)) 56 | local lr = lua:DoString([[ 57 | check = 0 58 | for i=min,max do 59 | if i%7 == 0 then 60 | check = check + i 61 | end 62 | end 63 | return result == check 64 | ]]) 65 | return lr and lr[0] 66 | end) 67 | if r then 68 | if not i then 69 | local lr = lua:DoString("return result")[0] 70 | local lc = lua:DoString("return check")[0] 71 | lua:Dispose()--销毁对象释放资源 72 | return "和不符合要求哦,"..tostring(ran1).."加"..tostring(ran2).."应为".. 73 | tostring(lc).. 74 | "但是你的结果为"..tostring(lr) 75 | end 76 | else 77 | lua:Dispose()--销毁对象释放资源 78 | return "代码报错啦,请检查是否有语法错误或运行时错误\r\n报错信息:\r\n".. 79 | (i:match("c# exception:XLua.LuaException: (.-)\r\n") or i) 80 | end 81 | lua:Dispose()--销毁对象释放资源 82 | return "" 83 | end 84 | -------------------------------------------------------------------------------- /LUATeach/Assets/script/levels/function_return.lua: -------------------------------------------------------------------------------- 1 | --函数返回值 2 | 3 | title = "函数返回值" 4 | type = "写代码" 5 | infomation = "学习函数返回值的设定" 6 | question = [[在前面的代码中,我们实现了一个函数,输入变量`a`、`b`,函数会自动输出两个数值的和。 7 | 8 | 但是一般来说,我们的需求远远不止这些,我们可能需要一个如下功能的函数: 9 | 10 | `执行函数,输入两个值,获取这两个值的和` 11 | 12 | 如果还是按上面几节的内容,我们只会输出这个值,并不能把这个值传递给其他的变量进行后续使用,如何解决这个需求呢? 13 | 14 | 我们可以使用函数的返回值来实现这个需求,结合上面的需求,我们可以用下面的代码实现: 15 | 16 | ```lua 17 | function add(a,b) 18 | return a+b 19 | end 20 | all = add(1,2) 21 | --这里all的值就是3了 22 | ``` 23 | 24 | 这里的`return`表示返回一个值,并且`立刻结束这个函数的运行` 25 | 26 | 同时,和输入值可以有多个一样,返回值也可以有多个 27 | 28 | ```lua 29 | function add(a,b) 30 | return a+b,"ok" 31 | end 32 | all, result = add(1,2) 33 | --这里all的值就是3了 34 | --这里result的值就是string "ok" 35 | ``` 36 | 37 | 下面问题来了,请设计一个函数`p`,可以按下面的调用方式来返回出物体的密度,返回值为number类型: 38 | 39 | ```lua 40 | --一个长方体的长宽高分别为a、b、c(单位米) 41 | a = 1 42 | b = 2 43 | c = 3 44 | --这个物体重量为m(单位克) 45 | m = 230 46 | --下面返回密度值 47 | --注:密度计算公式 密度 = 质量 / 体积 48 | result = p(a,b,c,m) 49 | ``` 50 | ]] 51 | 52 | code = [[ 53 | function p(a,b,c,m) 54 | --请补全代码 55 | end 56 | ]] 57 | explain = "至此,你已经初步掌握了函数的使用方法,后面将进行多个测试" 58 | 59 | check = function(s) 60 | local lua = CS.LUATeach.LuaEnv.LuaEnv.CreateLuaEnv() 61 | local a = math.random(1, 10) 62 | local b = math.random(1, 10) 63 | local c = math.random(1, 10) 64 | local m = math.random(1, 10) 65 | local r,i = pcall(function () 66 | lua:DoString(s) 67 | local lr = lua:DoString("return p("..tostring(a)..","..tostring(b)..","..tostring(c)..","..tostring(m)..")") 68 | return lr and lr[0] 69 | end) 70 | lua:Dispose()--销毁对象释放资源 71 | if r then 72 | if i and i == m/(a*b*c) then 73 | return "" 74 | else 75 | return "计算结果不对哦,请检查代码" 76 | end 77 | else 78 | return "代码报错啦,请检查是否有语法错误或运行时错误\r\n报错信息:\r\n".. 79 | (i:match("c# exception:XLua.LuaException: (.-)\r\n") or i) 80 | end 81 | end 82 | -------------------------------------------------------------------------------- /LUATeach/Assets/script/levels/function_return2.lua: -------------------------------------------------------------------------------- 1 | --函数返回值2 2 | 3 | title = "判断三角形合法性2" 4 | type = "写代码" 5 | infomation = "三角形合法性判断问题2" 6 | question = [[你需要使用前面几章的知识,来完成下面的题目 7 | 8 | 已知三个number类型的变量,分别代表三根木棒的长度 9 | 10 | 请判断,使用这三根木棒,是否可以组成一个三角形(两短边之和大于第三边) 11 | 12 | 请新建一个函数triangle,并可以用如下形式调用: 13 | 14 | ```lua 15 | result = triangle(1,2,3) 16 | ``` 17 | 18 | 如果可以组成,就返回true 19 | ]] 20 | 21 | code = [[ 22 | function triangle(a,b,c) 23 | 24 | end 25 | ]] 26 | explain = "难度开始上升了哦" 27 | 28 | check = function(s) 29 | local lua = CS.LUATeach.LuaEnv.LuaEnv.CreateLuaEnv() 30 | for n=1,20 do 31 | local a = math.random(1, 10) 32 | local b = math.random(1, 10) 33 | local c = math.random(1, 10) 34 | local r,i = pcall(function () 35 | lua:DoString(s) 36 | local lr = lua:DoString("return triangle("..tostring(a)..","..tostring(b)..","..tostring(c)..")") 37 | return lr and lr[0] 38 | end) 39 | if r then 40 | if a+b>c and b+c>a and a+c>b then 41 | if not i then 42 | lua:Dispose()--销毁对象释放资源 43 | return "当三边长度为"..tostring(a)..","..tostring(b)..","..tostring(c).."时,结果不对" 44 | end 45 | else 46 | if i then 47 | lua:Dispose()--销毁对象释放资源 48 | return "当三边长度为"..tostring(a)..","..tostring(b)..","..tostring(c).."时,结果不对" 49 | end 50 | end 51 | else 52 | lua:Dispose()--销毁对象释放资源 53 | return "代码报错啦,请检查是否有语法错误或运行时错误\r\n报错信息:\r\n".. 54 | (i:match("c# exception:XLua.LuaException: (.-)\r\n") or i) 55 | end 56 | end 57 | lua:Dispose()--销毁对象释放资源 58 | return "" 59 | end 60 | -------------------------------------------------------------------------------- /LUATeach/Assets/script/levels/function_return3.lua: -------------------------------------------------------------------------------- 1 | 2 | local oldtype = type 3 | title = "返回多个值" 4 | type = "写代码" 5 | infomation = "使用有多个返回值的function" 6 | question = [[你需要使用前面几章的知识,来完成下面的题目 7 | 8 | 已知2个number类型的变量,分别代表一个长方体的长和宽 9 | 10 | 请计算这个长方形的周长和面积 11 | 12 | 请新建一个函数`rectangle`,并可以用如下形式调用: 13 | 14 | ```lua 15 | area,len = rectangle(1,2) 16 | --结果: 17 | --area为2 18 | --len为6 19 | ``` 20 | 21 | 其中`area`为面积,`len`为周长 22 | ]] 23 | 24 | code = [[ 25 | function rectangle(a,b) 26 | 27 | end 28 | ]] 29 | explain = "函数就是个工具箱,需要熟练掌握" 30 | 31 | check = function(s) 32 | local lua = CS.LUATeach.LuaEnv.LuaEnv.CreateLuaEnv() 33 | for n=1,20 do 34 | local a = math.random(1, 10) 35 | local b = math.random(1, 10) 36 | local r,i = pcall(function () 37 | lua:DoString(s) 38 | local lr = lua:DoString("return rectangle("..tostring(a)..","..tostring(b)..")") 39 | return lr and {lr[0],lr[1]} 40 | end) 41 | if r then 42 | if not (oldtype(i) == "table" and i[1] == a*b and i[2] == (a+b)*2) then 43 | lua:Dispose()--销毁对象释放资源 44 | return "当两边长度为"..tostring(a)..","..tostring(b).."时,结果不对" 45 | end 46 | else 47 | lua:Dispose()--销毁对象释放资源 48 | return "代码报错啦,请检查是否有语法错误或运行时错误\r\n报错信息:\r\n".. 49 | (i:match("c# exception:XLua.LuaException: (.-)\r\n") or i) 50 | end 51 | end 52 | lua:Dispose()--销毁对象释放资源 53 | return "" 54 | end 55 | -------------------------------------------------------------------------------- /LUATeach/Assets/script/levels/loop1.lua: -------------------------------------------------------------------------------- 1 | 2 | title = "循环测试题1" 3 | type = "写代码" 4 | infomation = "打印数列" 5 | question = [[前面我们学习了循环语句,我们需要完成下面的任务 6 | 7 | 我们知道,`print`函数可以打印一行完整的输出 8 | 9 | 那么,已知变量`a`,请打印出下面的结果: 10 | 11 | (a为大于0的整数,且需要输出a行数据,数据从1开始,每行与上一行的差为2) 12 | 13 | ``` 14 | 1 15 | 3 16 | 5 17 | 7 18 | 9 19 | ``` 20 | 21 | (上面例子为当a为5的情况) 22 | ]] 23 | code = [[ 24 | --请补全代码 25 | --已知变量为a 26 | --需要用print输出要求的结果 27 | ]] 28 | explain = "下一题加大难度哦" 29 | 30 | check = function(s) 31 | 32 | if not s:find("for") and not s:find("while") then 33 | return "请使用循环语句来解决该问题" 34 | end 35 | 36 | local lua = CS.LUATeach.LuaEnv.LuaEnv.CreateLuaEnv() 37 | local ran = math.random(5,20) 38 | local r,i = pcall(function () 39 | lua:DoString("a="..tostring(ran)..[[ 40 | 41 | allPrintData = {} 42 | function print(...) 43 | arg = { ... } 44 | if #arg == 0 then table.insert(allPrintData,"nil") return end 45 | local logAll = {} 46 | for i=1,select("#", ...) do 47 | table.insert(logAll, tostring(arg[i])) 48 | end 49 | table.insert(allPrintData,table.concat(logAll, "\t")) 50 | end 51 | ]]) 52 | lua:DoString(s) 53 | local lr = lua:DoString("a="..tostring(ran)..[[ 54 | 55 | local check = {} 56 | for i=1,a do 57 | table.insert(check, tostring(2*i-1)) 58 | end 59 | 60 | return table.concat(allPrintData, "\r\n") == table.concat(check, "\r\n") 61 | ]]) 62 | return lr and lr[0] 63 | end) 64 | if r then 65 | if not i then 66 | local lr = lua:DoString([[return table.concat(allPrintData, "\r\n")]])[0] 67 | lua:Dispose()--销毁对象释放资源 68 | return "结果不符合要求哦,当a为"..tostring(ran).."时,你的结果为\r\n"..tostring(lr) 69 | end 70 | else 71 | lua:Dispose()--销毁对象释放资源 72 | return "代码报错啦,请检查是否有语法错误或运行时错误\r\n报错信息:\r\n".. 73 | (i:match("c# exception:XLua.LuaException: (.-)\r\n") or i) 74 | end 75 | lua:Dispose()--销毁对象释放资源 76 | return "" 77 | end 78 | -------------------------------------------------------------------------------- /LUATeach/Assets/script/levels/loop2.lua: -------------------------------------------------------------------------------- 1 | 2 | title = "循环测试题2" 3 | type = "写代码" 4 | infomation = "打印三角形" 5 | question = [[我们需要完成下面的任务 6 | 7 | 那么,已知变量`a`,请打印出下面的结果: 8 | 9 | (a为大于0的整数,且需要输出a行数据,第一行为一个*,后面每行多一个*) 10 | 11 | ``` 12 | * 13 | ** 14 | *** 15 | **** 16 | ***** 17 | ``` 18 | 19 | (上面例子为当a为5的情况) 20 | ]] 21 | code = [[ 22 | --请补全代码 23 | --已知变量为a 24 | --需要用print输出要求的结果 25 | ]] 26 | explain = "这一题难度怎么样?下一题会稍微再加点难度哦" 27 | 28 | check = function(s) 29 | 30 | if not s:find("for") and not s:find("while") then 31 | return "请使用循环语句来解决该问题" 32 | end 33 | 34 | local lua = CS.LUATeach.LuaEnv.LuaEnv.CreateLuaEnv() 35 | local ran = math.random(5,20) 36 | local r,i = pcall(function () 37 | lua:DoString("a="..tostring(ran)..[[ 38 | 39 | allPrintData = {} 40 | function print(...) 41 | arg = { ... } 42 | if #arg == 0 then table.insert(allPrintData,"nil") return end 43 | local logAll = {} 44 | for i=1,select("#", ...) do 45 | table.insert(logAll, tostring(arg[i])) 46 | end 47 | table.insert(allPrintData,table.concat(logAll, "\t")) 48 | end 49 | ]]) 50 | lua:DoString(s) 51 | local lr = lua:DoString("a="..tostring(ran)..[[ 52 | 53 | local check = {} 54 | for i=1,a do 55 | table.insert(check, string.rep("*", i)) 56 | end 57 | 58 | return table.concat(allPrintData, "\r\n") == table.concat(check, "\r\n") 59 | ]]) 60 | return lr and lr[0] 61 | end) 62 | if r then 63 | if not i then 64 | local lr = lua:DoString([[return table.concat(allPrintData, "\r\n")]])[0] 65 | lua:Dispose()--销毁对象释放资源 66 | return "结果不符合要求哦,当a为"..tostring(ran).."时,你的结果为\r\n"..tostring(lr) 67 | end 68 | else 69 | lua:Dispose()--销毁对象释放资源 70 | return "代码报错啦,请检查是否有语法错误或运行时错误\r\n报错信息:\r\n".. 71 | (i:match("c# exception:XLua.LuaException: (.-)\r\n") or i) 72 | end 73 | lua:Dispose()--销毁对象释放资源 74 | return "" 75 | end 76 | -------------------------------------------------------------------------------- /LUATeach/Assets/script/levels/loop3.lua: -------------------------------------------------------------------------------- 1 | 2 | title = "循环测试题3" 3 | type = "写代码" 4 | infomation = "打印数字三角形" 5 | question = [[我们需要完成下面的任务 6 | 7 | 那么,已知变量`a`,请打印出下面的结果: 8 | 9 | (a为大于0的整数,且需要输出a行数据,按图示规律输出) 10 | 11 | ``` 12 | 1 13 | 12 14 | 123 15 | 1234 16 | 12345 17 | 123456 18 | 1234567 19 | 12345678 20 | 123456789 21 | 12345678910 22 | 1234567891011 23 | ``` 24 | 25 | (上面例子为当a为11的情况) 26 | ]] 27 | code = [[ 28 | --请补全代码 29 | --已知变量为a 30 | --需要用print输出要求的结果 31 | ]] 32 | explain = "这一题难度怎么样?下一题我们来尝试解决实际问题" 33 | 34 | check = function(s) 35 | 36 | if not s:find("for") and not s:find("while") then 37 | return "请使用循环语句来解决该问题" 38 | end 39 | 40 | local lua = CS.LUATeach.LuaEnv.LuaEnv.CreateLuaEnv() 41 | local ran = math.random(5,20) 42 | local r,i = pcall(function () 43 | lua:DoString("a="..tostring(ran)..[[ 44 | 45 | allPrintData = {} 46 | function print(...) 47 | arg = { ... } 48 | if #arg == 0 then table.insert(allPrintData,"nil") return end 49 | local logAll = {} 50 | for i=1,select("#", ...) do 51 | table.insert(logAll, tostring(arg[i])) 52 | end 53 | table.insert(allPrintData,table.concat(logAll, "\t")) 54 | end 55 | ]]) 56 | lua:DoString(s) 57 | local lr = lua:DoString("a="..tostring(ran)..[[ 58 | 59 | local check = {} 60 | for i=1,a do 61 | local t = {} 62 | for j=1,i do 63 | table.insert(t, tostring(j)) 64 | end 65 | table.insert(check, table.concat(t)) 66 | end 67 | 68 | return table.concat(allPrintData, "\r\n") == table.concat(check, "\r\n") 69 | ]]) 70 | return lr and lr[0] 71 | end) 72 | if r then 73 | if not i then 74 | local lr = lua:DoString([[return table.concat(allPrintData, "\r\n")]])[0] 75 | lua:Dispose()--销毁对象释放资源 76 | return "结果不符合要求哦,当a为"..tostring(ran).."时,你的结果为\r\n"..tostring(lr) 77 | end 78 | else 79 | lua:Dispose()--销毁对象释放资源 80 | return "代码报错啦,请检查是否有语法错误或运行时错误\r\n报错信息:\r\n".. 81 | (i:match("c# exception:XLua.LuaException: (.-)\r\n") or i) 82 | end 83 | lua:Dispose()--销毁对象释放资源 84 | return "" 85 | end 86 | -------------------------------------------------------------------------------- /LUATeach/Assets/script/levels/loop4.lua: -------------------------------------------------------------------------------- 1 | 2 | title = "循环测试题4" 3 | type = "写代码" 4 | infomation = "猴子吃桃问题" 5 | question = [[有一只猴子,第一天摘了若干个桃子 ,当即吃了一半,但还觉得不过瘾 ,就又多吃了一个。 6 | 7 | 第2天早上又将剩下的桃子吃掉一半,还是觉得不过瘾,就又多吃了两个。 8 | 9 | 以后每天早上都吃了前一天剩下的一半加天数个(例如,第5天吃了前一天剩下的一半加5个)。 10 | 11 | 到第n天早上再想吃的时候,就只剩下一个桃子了。 12 | 13 | 那么,已知变量`a`为桃子总数,请打印出第一天的桃子数。 14 | 15 | 如:`a`为5时,输出`114` 16 | ]] 17 | code = [[ 18 | --请补全代码 19 | --已知变量为a 20 | --需要用print输出要求的结果 21 | ]] 22 | explain = "(猴子吃得下这么多🍑吗?)" 23 | 24 | check = function(s) 25 | 26 | if not s:find("for") and not s:find("while") then 27 | return "请使用循环语句来解决该问题" 28 | end 29 | 30 | local lua = CS.LUATeach.LuaEnv.LuaEnv.CreateLuaEnv() 31 | local ran = math.random(5,20) 32 | local r,i = pcall(function () 33 | lua:DoString("a="..tostring(ran)..[[ 34 | 35 | allPrintData = {} 36 | function print(...) 37 | arg = { ... } 38 | if #arg == 0 then table.insert(allPrintData,"nil") return end 39 | local logAll = {} 40 | for i=1,select("#", ...) do 41 | table.insert(logAll, tostring(arg[i])) 42 | end 43 | table.insert(allPrintData,table.concat(logAll, "\t")) 44 | end 45 | ]]) 46 | lua:DoString(s) 47 | local lr = lua:DoString("a="..tostring(ran)..[[ 48 | 49 | local check = 1 50 | for i=a-1,1,-1 do 51 | check = 2 * (check + i) 52 | end 53 | 54 | return table.concat(allPrintData, "\r\n") == tostring(check) 55 | ]]) 56 | return lr and lr[0] 57 | end) 58 | if r then 59 | if not i then 60 | local lr = lua:DoString([[return table.concat(allPrintData, "\r\n")]])[0] 61 | lua:Dispose()--销毁对象释放资源 62 | return "结果不符合要求哦,当a为"..tostring(ran).."时,你的结果为\r\n"..tostring(lr) 63 | end 64 | else 65 | lua:Dispose()--销毁对象释放资源 66 | return "代码报错啦,请检查是否有语法错误或运行时错误\r\n报错信息:\r\n".. 67 | (i:match("c# exception:XLua.LuaException: (.-)\r\n") or i) 68 | end 69 | lua:Dispose()--销毁对象释放资源 70 | return "" 71 | end 72 | -------------------------------------------------------------------------------- /LUATeach/Assets/script/levels/string.byte.lua: -------------------------------------------------------------------------------- 1 | 2 | title = "string.byte" 3 | type = "写代码" 4 | infomation = "从字符串提取数值" 5 | question = [[string.byte(s [, i [, j ] ]) 6 | 7 | 返回字符 s[i]、s[i + 1]、s[i + 2]、······、s[j] 所对应的 ASCII 码。i 的默认值为 1,即第一个字节,j 的默认值为 i 。 8 | 9 | 这个函数功能刚好和前面的string.char相反,是提取字符串中实际的数值。 10 | 11 | 示例代码: 12 | 13 | ```lua 14 | str = "12345" 15 | print(string.byte(str,2)) 16 | print(str:byte(2))--也可以这样 17 | print(str:byte())--不填默认是1 18 | 19 | -->输出(十进制数据) 20 | 50 21 | 50 22 | 49 23 | ``` 24 | 25 | 请完成下面的任务: 26 | 27 | 已知字符串`s` 28 | 29 | 请把`s`中代表的数据,全部相加,并打印出来 30 | ]] 31 | code = [[ 32 | --请补全代码 33 | --需要用print输出要求的结果 34 | --一共1行 35 | --已知变量s 36 | ]] 37 | explain = "字符串本质就是一串数字" 38 | 39 | check = function(s) 40 | local lua = CS.LUATeach.LuaEnv.LuaEnv.CreateLuaEnv() 41 | local ran = math.random(100,150) 42 | local r,i = pcall(function () 43 | lua:DoString("local n="..tostring(ran)..[[ 44 | 45 | local t={} 46 | for i=1,n do 47 | t[i] = string.char(i) 48 | end 49 | s = table.concat(t) 50 | allPrintData = {} 51 | function print(...) 52 | arg = { ... } 53 | if #arg == 0 then table.insert(allPrintData,"nil") return end 54 | local logAll = {} 55 | for i=1,select("#", ...) do 56 | table.insert(logAll, tostring(arg[i])) 57 | end 58 | table.insert(allPrintData,table.concat(logAll, "\t")) 59 | end 60 | ]]) 61 | lua:DoString(s) 62 | local lr = lua:DoString("local n="..tostring(ran)..[[ 63 | 64 | local temp = {} 65 | check = 0 66 | for i=1,n do 67 | check = check + i 68 | end 69 | check = tostring(check) 70 | return table.concat(allPrintData, "\r\n") == check]]) 71 | return lr and lr[0] 72 | end) 73 | if r then 74 | if not i then 75 | local lr = lua:DoString([[return table.concat(allPrintData, "\r\n")]])[0] 76 | local lc = lua:DoString([[return check]])[0] 77 | lua:Dispose()--销毁对象释放资源 78 | return "结果不符合要求哦,应输出"..lc..",但你输出的是"..lr 79 | end 80 | else 81 | lua:Dispose()--销毁对象释放资源 82 | return "代码报错啦,请检查是否有语法错误或运行时错误\r\n报错信息:\r\n".. 83 | (i:match("c# exception:XLua.LuaException: (.-)\r\n") or i) 84 | end 85 | lua:Dispose()--销毁对象释放资源 86 | return "" 87 | end 88 | -------------------------------------------------------------------------------- /LUATeach/Assets/script/levels/string.char.lua: -------------------------------------------------------------------------------- 1 | 2 | title = "string.char" 3 | type = "写代码" 4 | infomation = "ascii转字符串" 5 | question = [[string.char (...) 6 | 7 | 接收 0 个或更多的整数(整数范围:0~255),返回这些整数所对应的 ASCII 码字符组成的字符串。当参数为空时,默认是一个 0。 8 | 9 | 如果上一章节有认真学习过了的话,这段话应该是很好理解的。实质上就是把计算机认识的一串数字,变成字符串变量,并且字符串内的数据就是要存的那串数据。 10 | 11 | 示例代码: 12 | 13 | ```lua 14 | str1 = string.char(0x30,0x31,0x32,0x33) 15 | str2 = string.char(0x01,0x02,0x30,0x03,0x44) 16 | print(str1) 17 | print(str2) 18 | 19 | -->输出(不可见字符用�代替) 20 | 0123 21 | ��0�D 22 | ``` 23 | 24 | 请完成下面的任务: 25 | 26 | 已知一个字符串的每个字符在数组`t`中按顺序排列 27 | 28 | 请根据t的值,打印出字符串内容(一行数据) 29 | 30 | 注:这个字符串存储的不一定是可见的字符 31 | ]] 32 | code = [[ 33 | --请补全代码 34 | --需要用print输出要求的结果 35 | --一共1行 36 | --已知变量t 37 | ]] 38 | explain = "字符串本质就是一串数字" 39 | 40 | check = function(s) 41 | local lua = CS.LUATeach.LuaEnv.LuaEnv.CreateLuaEnv() 42 | local ran = math.random(100,150) 43 | local r,i = pcall(function () 44 | lua:DoString("local n="..tostring(ran)..[[ 45 | 46 | t={} 47 | for i=1,n do 48 | t[i] = i 49 | end 50 | allPrintData = {} 51 | function print(...) 52 | arg = { ... } 53 | if #arg == 0 then table.insert(allPrintData,"nil") return end 54 | local logAll = {} 55 | for i=1,select("#", ...) do 56 | table.insert(logAll, tostring(arg[i])) 57 | end 58 | table.insert(allPrintData,table.concat(logAll, "\t")) 59 | end 60 | ]]) 61 | lua:DoString(s) 62 | local lr = lua:DoString("local n="..tostring(ran)..[[ 63 | 64 | local temp = {} 65 | for i=1,n do 66 | temp[i] = string.char(i) 67 | end 68 | return table.concat(allPrintData, "\r\n") == table.concat(temp)]]) 69 | return lr and lr[0] 70 | end) 71 | if r then 72 | if not i then 73 | lua:Dispose()--销毁对象释放资源 74 | return "结果不符合要求哦" 75 | end 76 | else 77 | lua:Dispose()--销毁对象释放资源 78 | return "代码报错啦,请检查是否有语法错误或运行时错误\r\n报错信息:\r\n".. 79 | (i:match("c# exception:XLua.LuaException: (.-)\r\n") or i) 80 | end 81 | lua:Dispose()--销毁对象释放资源 82 | return "" 83 | end 84 | -------------------------------------------------------------------------------- /LUATeach/Assets/script/levels/string.find.lua: -------------------------------------------------------------------------------- 1 | 2 | title = "string.find" 3 | type = "写代码" 4 | infomation = "查找字符串内容" 5 | question = [[string.find(s, p [, init [, plain] ]) 6 | 7 | 这个函数会在字符串`s`中,寻找匹配`p`字符串的数据。如果成功找到,那么会返回`p`字符串在`s`字符串中出现的开始位置和结束位置;如果没找到,那么就返回`nil`。 8 | 9 | 第三个参数`init`默认为`1`,表示从第几个字符开始匹配,当`init`为负数时,表示从`s`字符串的倒数第`-init`个字符处开始匹配。 10 | 11 | 第四个参数`plain`默认为`false`,当其为`true`时,只会把`p`看成一个字符串对待。 12 | 13 | ========= 14 | 15 | 可能你会奇怪,第四个参数有什么存在的必要吗?`p`不是本来就应该是个字符串吗? 16 | 17 | 实际上,lua中的匹配默认意义是`正则匹配`,同时,这里的正则与其它语言也有些许不同。 18 | 19 | 由于篇幅有限,本节和下面的几节涉及匹配内容时,均不会考虑正则的使用方法,Lua正则教程将会在最后几节单独详细地列出来。 20 | 21 | 第四个参数为`true`时,便不会使用正则功能。 22 | 23 | ========= 24 | 25 | 示例代码: 26 | 27 | ```lua 28 | --只会匹配到第一个 29 | print(string.find("abc abc", "ab")) 30 | -- 从索引为2的位置开始匹配字符串:ab 31 | print(string.find("abc abc", "ab", 2)) 32 | -- 从索引为5的位置开始匹配字符串:ab 33 | print(string.find("abc abc", "ab", -3)) 34 | 35 | -->输出 36 | 1 2 37 | 5 6 38 | 5 6 39 | ``` 40 | 41 | 请完成下面的任务: 42 | 43 | 已知字符串`s`,里面有很多相同的字符串 44 | 45 | 请找出字符串`s`中,所有字符串`awsl`的位置 46 | 47 | 使用print打印结果,结果一行一个 48 | 49 | 如字符串`12awslawslaw` 50 | 51 | 打印结果: 52 | 53 | ``` 54 | 3 55 | 7 56 | ``` 57 | ]] 58 | code = [[ 59 | --已知变量s 60 | --需要用print输出要求的结果 61 | ]] 62 | explain = "find可以快速找到指定字符串的位置" 63 | 64 | check = function(s) 65 | local lua = CS.LUATeach.LuaEnv.LuaEnv.CreateLuaEnv() 66 | local ran = math.random(3,7) 67 | local ran2 = math.random(1,999) 68 | local r,i = pcall(function () 69 | lua:DoString("s=string.rep('aaa',"..tostring(ran2)..")..string.rep('awsl123',"..tostring(ran)..[[) 70 | 71 | allPrintData = {} 72 | function print(...) 73 | arg = { ... } 74 | if #arg == 0 then table.insert(allPrintData,"nil") return end 75 | local logAll = {} 76 | for i=1,select("#", ...) do 77 | table.insert(logAll, tostring(arg[i])) 78 | end 79 | table.insert(allPrintData,table.concat(logAll, "\t")) 80 | end 81 | ]]) 82 | lua:DoString(s) 83 | lua:DoString("s=string.rep('aaa',"..tostring(ran2)..")..string.rep('awsl123',"..tostring(ran)..")") 84 | local lr = lua:DoString([[ 85 | check = {} 86 | local last = 1 87 | while true do 88 | local l = s:find("awsl",last) 89 | if l then 90 | table.insert(check,tostring(l)) 91 | last = l+1 92 | else 93 | break 94 | end 95 | end 96 | 97 | return table.concat(allPrintData, "\r\n") == table.concat(check, "\r\n")]]) 98 | return lr and lr[0] 99 | end) 100 | if r then 101 | if not i then 102 | local lr = lua:DoString([[return table.concat(allPrintData, "\r\n")]])[0] 103 | local lc = lua:DoString([[return table.concat(check, "\r\n")]])[0] 104 | lua:Dispose()--销毁对象释放资源 105 | return "结果不符合要求哦,应输出\r\n"..lc.."\r\n但你输出的是\r\n"..lr 106 | end 107 | else 108 | lua:Dispose()--销毁对象释放资源 109 | return "代码报错啦,请检查是否有语法错误或运行时错误\r\n报错信息:\r\n".. 110 | (i:match("c# exception:XLua.LuaException: (.-)\r\n") or i) 111 | end 112 | lua:Dispose()--销毁对象释放资源 113 | return "" 114 | end 115 | -------------------------------------------------------------------------------- /LUATeach/Assets/script/levels/string.format.lua: -------------------------------------------------------------------------------- 1 | 2 | title = "string.format" 3 | type = "写代码" 4 | infomation = "字符串格式化输出" 5 | question = [[string.format(formatstring, ...) 6 | 7 | 按照格式化参数`formatstring`,返回后面`...`内容的格式化版本。 8 | 9 | 编写格式化字符串的规则与标准 c 语言中 printf 函数的规则基本相同: 10 | 11 | 它由常规文本和指示组成,这些指示控制了每个参数应放到格式化结果的什么位置,及如何放入它们。 12 | 13 | 一个指示由字符`%`加上一个字母组成,这些字母指定了如何格式化参数,例如`d`用于十进制数、`x`用于十六进制数、`o`用于八进制数、`f`用于浮点数、`s`用于字符串等。 14 | 15 | 在字符`%`和字母之间可以再指定一些其他选项,用于控制格式的细节。 16 | 17 | 示例代码: 18 | 19 | ```lua 20 | print(string.format("%.4f", 3.1415926)) -- 保留4位小数 21 | print(string.format("%d %x %o", 31, 31, 31))-- 十进制数31转换成不同进制 22 | d,m,y = 29,7,2015 23 | print(string.format("%s %02d/%02d/%d", "today is:", d, m, y)) 24 | --控制输出2位数字,并在前面补0 25 | 26 | -->输出 27 | 3.1416 28 | 31 1f 37 29 | today is: 29/07/2015 30 | ``` 31 | 32 | 请完成下面的任务: 33 | 34 | 已知一个变量`n`,为`number`类型证书 35 | 36 | 打印出`n:`连上n值的字符串 37 | ]] 38 | code = [[ 39 | --请补全代码 40 | --需要用print输出要求的结果 41 | --一共1行 42 | --已知变量n 43 | ]] 44 | explain = "大小写也可以一键转换啦" 45 | 46 | check = function(s) 47 | 48 | if not s:find("format") then 49 | return "请使用格式化函数来解决该问题" 50 | end 51 | 52 | local lua = CS.LUATeach.LuaEnv.LuaEnv.CreateLuaEnv() 53 | local ran = math.random(100,9999) 54 | local r,i = pcall(function () 55 | lua:DoString("n="..tostring(ran)..[[ 56 | 57 | allPrintData = {} 58 | function print(...) 59 | arg = { ... } 60 | if #arg == 0 then table.insert(allPrintData,"nil") return end 61 | local logAll = {} 62 | for i=1,select("#", ...) do 63 | table.insert(logAll, tostring(arg[i])) 64 | end 65 | table.insert(allPrintData,table.concat(logAll, "\t")) 66 | end 67 | ]]) 68 | lua:DoString(s) 69 | lua:DoString("n="..tostring(ran)) 70 | local lr = lua:DoString([[return table.concat(allPrintData, "\r\n") == "n:]]..tostring(ran).."\"") 71 | return lr and lr[0] 72 | end) 73 | if r then 74 | if not i then 75 | local lr = lua:DoString([[return table.concat(allPrintData, "\r\n")]])[0] 76 | local lc = "n:"..tostring(ran) 77 | lua:Dispose()--销毁对象释放资源 78 | return "结果不符合要求哦,应输出"..lc..",但你输出的是"..lr 79 | end 80 | else 81 | lua:Dispose()--销毁对象释放资源 82 | return "代码报错啦,请检查是否有语法错误或运行时错误\r\n报错信息:\r\n".. 83 | (i:match("c# exception:XLua.LuaException: (.-)\r\n") or i) 84 | end 85 | lua:Dispose()--销毁对象释放资源 86 | return "" 87 | end 88 | -------------------------------------------------------------------------------- /LUATeach/Assets/script/levels/string.gsub.lua: -------------------------------------------------------------------------------- 1 | 2 | title = "string.gsub" 3 | type = "写代码" 4 | infomation = "替换字符串" 5 | question = [[string.gsub(s, p, r [, n]) 6 | 7 | 将目标字符串`s`中所有的子串`p`替换成字符串`r`。 8 | 9 | 可选参数`n`,表示限制替换次数。 10 | 11 | 返回值有两个,第一个是被替换后的字符串,第二个是替换了多少次。 12 | 13 | `特别提示:这个函数的目标字符串s,也是支持正则的` 14 | 15 | 下面是例子: 16 | 17 | ```lua 18 | print(string.gsub("Lua Lua Lua", "Lua", "hello")) 19 | print(string.gsub("Lua Lua Lua", "Lua", "hello", 2)) --指明第四个参数 20 | 21 | -->打印的结果: 22 | hello hello hello 3 23 | hello hello Lua 2 24 | ``` 25 | 26 | 同样的,我们也可以使用冒号来简化语法,像下面这样: 27 | 28 | ```lua 29 | s = "12345" 30 | r = s:gsub("2","b") 31 | ``` 32 | 33 | 请完成下面的任务: 34 | 35 | 已知字符串变量`s`,请分别打印出(每种一行): 36 | 37 | 把字符串`s`中,前5个`a`,替换为`b` 38 | 39 | 把字符串`s`中,前3个`c`,替换为`xxx` 40 | 41 | 把结果打印出来,一行数据 42 | ]] 43 | code = [[ 44 | --请补全代码 45 | --已知变量为s 46 | --需要用print输出要求的结果 47 | --一共1行 48 | ]] 49 | explain = "string.match和string.gmatch匹配函数,由于涉及正则,太过复杂,请自行上网查找资料" 50 | 51 | check = function(s) 52 | local lua = CS.LUATeach.LuaEnv.LuaEnv.CreateLuaEnv() 53 | local ran = math.random(5,10) 54 | local ran2 = math.random(1,10) 55 | local r,i = pcall(function () 56 | lua:DoString("s=string.rep('u',"..tostring(ran2)..")..string.rep('aca',"..tostring(ran)..[[) 57 | 58 | allPrintData = {} 59 | function print(...) 60 | arg = { ... } 61 | if #arg == 0 then table.insert(allPrintData,"nil") return end 62 | local logAll = {} 63 | for i=1,select("#", ...) do 64 | table.insert(logAll, tostring(arg[i])) 65 | end 66 | table.insert(allPrintData,table.concat(logAll, "\t")) 67 | end 68 | ]]) 69 | lua:DoString(s) 70 | local lr = lua:DoString("s=string.rep('u',"..tostring(ran2)..")..string.rep('aca',"..tostring(ran)..[[) 71 | 72 | check = s:gsub("a","b",5):gsub("c","xxx",3) 73 | 74 | return table.concat(allPrintData, "\r\n") == check 75 | ]]) 76 | return lr and lr[0] 77 | end) 78 | if r then 79 | if not i then 80 | local lr = lua:DoString([[return table.concat(allPrintData, "\r\n")]])[0] 81 | local lc = lua:DoString([[return check]])[0] 82 | lua:Dispose()--销毁对象释放资源 83 | return "结果不符合要求哦,应输出\r\n"..lc.."\r\n但你输出的是\r\n"..lr 84 | end 85 | else 86 | lua:Dispose()--销毁对象释放资源 87 | return "代码报错啦,请检查是否有语法错误或运行时错误\r\n报错信息:\r\n".. 88 | (i:match("c# exception:XLua.LuaException: (.-)\r\n") or i) 89 | end 90 | lua:Dispose()--销毁对象释放资源 91 | return "" 92 | end 93 | -------------------------------------------------------------------------------- /LUATeach/Assets/script/levels/string.len.lua: -------------------------------------------------------------------------------- 1 | 2 | title = "string.len" 3 | type = "写代码" 4 | infomation = "获取字符串长度" 5 | question = [[string.len(s) 6 | 7 | 接收一个字符串,返回它的长度。 8 | 9 | 示例代码: 10 | 11 | ```lua 12 | s = "hello lua" 13 | print(string.len(s)) 14 | --输出结果: 15 | 9 16 | 17 | --同时也可以使用简便语法 18 | print(s:len()) 19 | ``` 20 | 21 | 请完成下面的任务: 22 | 23 | 新建一个变量`s`,使数据内容为810个`114514` 24 | 25 | 并打印出字符串`s`的长度 26 | ]] 27 | code = [[ 28 | --请补全代码 29 | --需要用print输出要求的结果 30 | --一共1行 31 | --并按要求新建s,存入数据 32 | ]] 33 | explain = "你也可以使用 # 运算符来获取 Lua 字符串的长度。" 34 | 35 | check = function(s) 36 | local lua = CS.LUATeach.LuaEnv.LuaEnv.CreateLuaEnv() 37 | local r,i = pcall(function () 38 | lua:DoString([[ 39 | 40 | allPrintData = {} 41 | function print(...) 42 | arg = { ... } 43 | if #arg == 0 then table.insert(allPrintData,"nil") return end 44 | local logAll = {} 45 | for i=1,select("#", ...) do 46 | table.insert(logAll, tostring(arg[i])) 47 | end 48 | table.insert(allPrintData,table.concat(logAll, "\t")) 49 | end 50 | ]]) 51 | lua:DoString(s) 52 | local lr = lua:DoString([[ 53 | return table.concat(allPrintData, "\r\n") == tostring(string.rep("114514",810):len()) and s == string.rep("114514",810) 54 | ]]) 55 | return lr and lr[0] 56 | end) 57 | if r then 58 | if not i then 59 | lua:Dispose()--销毁对象释放资源 60 | return "结果不符合要求哦" 61 | end 62 | else 63 | lua:Dispose()--销毁对象释放资源 64 | return "代码报错啦,请检查是否有语法错误或运行时错误\r\n报错信息:\r\n".. 65 | (i:match("c# exception:XLua.LuaException: (.-)\r\n") or i) 66 | end 67 | lua:Dispose()--销毁对象释放资源 68 | return "" 69 | end 70 | -------------------------------------------------------------------------------- /LUATeach/Assets/script/levels/string.low.lua: -------------------------------------------------------------------------------- 1 | 2 | title = "string.lower" 3 | type = "写代码" 4 | infomation = "字符串大小写转换" 5 | question = [[string.lower(s) 6 | 7 | 接收一个字符串 s,返回一个把所有大写字母变成小写字母的字符串。 8 | 9 | string.upper(s) 10 | 11 | 接收一个字符串 s,返回一个把所有小写字母变成大写字母的字符串。 12 | 13 | 示例代码: 14 | 15 | ```lua 16 | s = "hello lua" 17 | print(string.upper(s)) 18 | print(string.lower(s)) 19 | --输出结果: 20 | HELLO LUA 21 | hello lua 22 | 23 | --同时也可以使用简便语法 24 | print(s:upper()) 25 | print(s:lower()) 26 | ``` 27 | 28 | 请完成下面的任务: 29 | 30 | 已知一个变量`s`,打印出全是大写字母的s字符串 31 | ]] 32 | code = [[ 33 | --请补全代码 34 | --需要用print输出要求的结果 35 | --一共1行 36 | --已知变量s 37 | ]] 38 | explain = "大小写也可以一键转换啦" 39 | 40 | check = function(s) 41 | local lua = CS.LUATeach.LuaEnv.LuaEnv.CreateLuaEnv() 42 | local r,i = pcall(function () 43 | lua:DoString([[s=string.rep("abc",200) 44 | 45 | allPrintData = {} 46 | function print(...) 47 | arg = { ... } 48 | if #arg == 0 then table.insert(allPrintData,"nil") return end 49 | local logAll = {} 50 | for i=1,select("#", ...) do 51 | table.insert(logAll, tostring(arg[i])) 52 | end 53 | table.insert(allPrintData,table.concat(logAll, "\t")) 54 | end 55 | ]]) 56 | lua:DoString(s) 57 | local lr = lua:DoString([[ 58 | return table.concat(allPrintData, "\r\n") == string.rep("ABC",200) 59 | ]]) 60 | return lr and lr[0] 61 | end) 62 | if r then 63 | if not i then 64 | lua:Dispose()--销毁对象释放资源 65 | return "结果不符合要求哦" 66 | end 67 | else 68 | lua:Dispose()--销毁对象释放资源 69 | return "代码报错啦,请检查是否有语法错误或运行时错误\r\n报错信息:\r\n".. 70 | (i:match("c# exception:XLua.LuaException: (.-)\r\n") or i) 71 | end 72 | lua:Dispose()--销毁对象释放资源 73 | return "" 74 | end 75 | -------------------------------------------------------------------------------- /LUATeach/Assets/script/levels/string.lua: -------------------------------------------------------------------------------- 1 | 2 | title = "string" 3 | type = "写代码" 4 | infomation = "字符串概念基础知识" 5 | question = [[这一节我们来讲解字符串的本质 6 | 7 | `字符串`,是用来存储一串字符的,但是`它的本质就是一串数字`。如何也一串数字来代表一串字符呢? 8 | 9 | 在计算机中,每一个符号都对应着一个数字,但是在讲解这个知识之前,我们了解一下补充知识: 10 | 11 | ``` 12 | 在大多数编程语言中,我们使用0x开头来表示这个数字是16进制的。 13 | 比如 14 | 10等价于0x0a 15 | 256等价于0xff 16 | ``` 17 | 18 | 接下来,你需要了解,每一个符号都对应着一个数字,比如: 19 | 20 | `0`对应着`0x30`、`1`对应着`0x31` 21 | 22 | `a`对应着`0x61`、`b`对应着`0x62` 23 | 24 | `A`对应着`0x41`、`B`对应着`0x42` 25 | 26 | 上面的编码规则,我们称之为ascii码,具体想了解可以打开下面的网址查看: 27 | 28 | http://ascii.911cha.com/ 29 | 30 | 当然,1字节最大为0xff,即256,只能存下一部分符号,大部分的中文按某些编码,一个中文占用2或3个字节 31 | 32 | 计算机如何解析这些数据,我们不需要了解,当你知道了上面的知识后,你应该可以理解下面的描述: 33 | 34 | ``` 35 | 字符串"apple"实际上的内容就是下面的一串数字: 36 | 0x61,0x70,0x70,0x6c,0x65 37 | ``` 38 | 39 | 同时,lua的字符串中可以保存任何数值,即使是0x00这种不代表任何含义的数,也可以保存 40 | 41 | `补充:在其他语言中(如C),0x00代表字符串结束,但是在lua中并不是这样。lua的字符串每字节可以存储任意的一字节数据。` 42 | 43 | 比如下面的描述: 44 | 45 | ``` 46 | 有一串lua字符串中的数据为: 47 | 0x01,0x02,0x30,0x00,0x44 48 | 实际人能看到的(不可见字符用�代替): 49 | ��0�D 50 | 当然,你不能说你看不见的数据就不存在,他们都完好无损地在这个字符串中 51 | ``` 52 | 53 | 下面你只需要回答一个简单的问题,填到下面的框里就可以了: 54 | 55 | 一串字符串数据如下,它的实际内容是什么? 56 | 57 | (指人能看见的字符串内容,如`abcd`) 58 | 59 | 0x62,0x61,0x6e,0x61,0x6e,0x61 60 | ]] 61 | code = "" 62 | explain = "需要深刻理解字符串的实际含义" 63 | 64 | check = function(s) 65 | 66 | if not s:find("banana") then 67 | return "答案不对哦" 68 | end 69 | return "" 70 | end 71 | -------------------------------------------------------------------------------- /LUATeach/Assets/script/levels/string.rep.lua: -------------------------------------------------------------------------------- 1 | 2 | title = "string.rep" 3 | type = "写代码" 4 | infomation = "重复字符串" 5 | question = [[string.rep(s, n) 6 | 7 | 返回字符串 s 的 n 次拷贝。 8 | 9 | 示例代码: 10 | 11 | ```lua 12 | print(string.rep("abc", 3)) 13 | --输出结果: 14 | abcabcabc 15 | ``` 16 | 17 | 请完成下面的任务: 18 | 19 | 打印一行数据,数据内容为810个`114514` 20 | ]] 21 | code = [[ 22 | --请补全代码 23 | --需要用print输出要求的结果 24 | --一共1行 25 | ]] 26 | explain = "终于不用拿循环来造字符串了" 27 | 28 | check = function(s) 29 | local lua = CS.LUATeach.LuaEnv.LuaEnv.CreateLuaEnv() 30 | local r,i = pcall(function () 31 | lua:DoString([[ 32 | 33 | allPrintData = {} 34 | function print(...) 35 | arg = { ... } 36 | if #arg == 0 then table.insert(allPrintData,"nil") return end 37 | local logAll = {} 38 | for i=1,select("#", ...) do 39 | table.insert(logAll, tostring(arg[i])) 40 | end 41 | table.insert(allPrintData,table.concat(logAll, "\t")) 42 | end 43 | ]]) 44 | lua:DoString(s) 45 | local lr = lua:DoString([[ 46 | return table.concat(allPrintData, "\r\n") == string.rep("114514",810) 47 | ]]) 48 | return lr and lr[0] 49 | end) 50 | if r then 51 | if not i then 52 | lua:Dispose()--销毁对象释放资源 53 | return "结果不符合要求哦" 54 | end 55 | else 56 | lua:Dispose()--销毁对象释放资源 57 | return "代码报错啦,请检查是否有语法错误或运行时错误\r\n报错信息:\r\n".. 58 | (i:match("c# exception:XLua.LuaException: (.-)\r\n") or i) 59 | end 60 | lua:Dispose()--销毁对象释放资源 61 | return "" 62 | end 63 | -------------------------------------------------------------------------------- /LUATeach/Assets/script/levels/string.sub.lua: -------------------------------------------------------------------------------- 1 | 2 | title = "string.sub" 3 | type = "写代码" 4 | infomation = "切割字符串" 5 | question = [[接下来几节会讲解string库的各种接口 6 | 7 | `string.sub(s, i [, j])` 8 | 9 | 返回字符串 `s` 中,从索引 `i` 到索引 `j` 之间的子字符串。 10 | 11 | i 可以为负数,表示倒数第几个字符。 12 | 13 | 当 j 缺省时,默认为 -1,也就是字符串 s 的最后位置。 14 | 15 | 当索引 i 在字符串 s 的位置在索引 j 的后面时,将返回一个空字符串。 16 | 17 | 下面是例子: 18 | 19 | ```lua 20 | print(string.sub("Hello Lua", 4, 7)) 21 | print(string.sub("Hello Lua", 2)) 22 | print(string.sub("Hello Lua", 2, 1)) 23 | print(string.sub("Hello Lua", -3, -1)) 24 | 25 | -->打印的结果: 26 | lo L 27 | ello Lua 28 | 29 | Lua 30 | ``` 31 | 32 | 值得注意的是,我们可以使用冒号来简化语法,像下面这样: 33 | 34 | ```lua 35 | s = "12345" 36 | s1 = string.sub(s, 4, 7) 37 | s2 = s:sub(4, 7) 38 | --两种写法是等价关系 39 | ``` 40 | 41 | 请完成下面的任务: 42 | 43 | 已知字符串变量`s`,请分别打印出(每种一行): 44 | 45 | `s`从第4个字符开始,到最后的值 46 | 47 | `s`从第1个字符开始,到倒数第3个字符的值 48 | 49 | `s`从倒数第5个字符开始,到倒数第2个字符的值 50 | ]] 51 | code = [[ 52 | --请补全代码 53 | --已知变量为s 54 | --需要用print输出要求的结果 55 | --一共三行 56 | ]] 57 | explain = "如果你只是想对字符串中的单个字节进行检查,使用 string.byte 函数通常会更为高效。" 58 | 59 | check = function(s) 60 | local lua = CS.LUATeach.LuaEnv.LuaEnv.CreateLuaEnv() 61 | local ran = math.random(111111,999999) 62 | local r,i = pcall(function () 63 | lua:DoString("s='abcdefg"..tostring(ran)..[[' 64 | 65 | allPrintData = {} 66 | function print(...) 67 | arg = { ... } 68 | if #arg == 0 then table.insert(allPrintData,"nil") return end 69 | local logAll = {} 70 | for i=1,select("#", ...) do 71 | table.insert(logAll, tostring(arg[i])) 72 | end 73 | table.insert(allPrintData,table.concat(logAll, "\t")) 74 | end 75 | ]]) 76 | lua:DoString(s) 77 | local lr = lua:DoString("s='abcdefg"..tostring(ran)..[[' 78 | 79 | check = {} 80 | table.insert(check, s:sub(4)) 81 | table.insert(check, s:sub(1,-3)) 82 | table.insert(check, s:sub(-5,-2)) 83 | 84 | return table.concat(allPrintData, "\r\n") == table.concat(check, "\r\n") 85 | ]]) 86 | return lr and lr[0] 87 | end) 88 | if r then 89 | if not i then 90 | local lr = lua:DoString([[return table.concat(allPrintData, "\r\n")]])[0] 91 | lua:Dispose()--销毁对象释放资源 92 | return "结果不符合要求哦,当s为abcdefg"..tostring(ran).."时,你的结果为\r\n"..tostring(lr) 93 | end 94 | else 95 | lua:Dispose()--销毁对象释放资源 96 | return "代码报错啦,请检查是否有语法错误或运行时错误\r\n报错信息:\r\n".. 97 | (i:match("c# exception:XLua.LuaException: (.-)\r\n") or i) 98 | end 99 | lua:Dispose()--销毁对象释放资源 100 | return "" 101 | end 102 | -------------------------------------------------------------------------------- /LUATeach/Assets/script/levels/table.concat.lua: -------------------------------------------------------------------------------- 1 | 2 | title = "table.concat" 3 | type = "写代码" 4 | infomation = "连接table" 5 | question = [[table.concat (table [, sep [, i [, j ] ] ]) 6 | 7 | 将元素是`string`或者`number`类型的`table`,每个元素连接起来变成字符串并返回。 8 | 9 | 可选参数`sep`,表示连接间隔符,默认为空。 10 | 11 | `i`和`j`表示元素起始和结束的下标。 12 | 13 | 下面是例子: 14 | 15 | ```lua 16 | local a = {1, 3, 5, "hello" } 17 | print(table.concat(a)) 18 | print(table.concat(a, "|")) 19 | 20 | -->打印的结果: 21 | 135hello 22 | 1|3|5|hello 23 | ``` 24 | 25 | 请完成下面的任务: 26 | 27 | 已知`table`变量`t`, 28 | 29 | 将`t`中的结果全部连起来 30 | 31 | 间隔符使用`,` 32 | 33 | 并使用print打印出来 34 | ]] 35 | code = [[ 36 | --请补全代码 37 | --已知变量为t 38 | --需要用print输出要求的结果 39 | --一共1行 40 | ]] 41 | explain = "这个函数主要是在连接一堆字符串时使用" 42 | 43 | check = function(s) 44 | local lua = CS.LUATeach.LuaEnv.LuaEnv.CreateLuaEnv() 45 | local ran = math.random(5,10) 46 | local r,i = pcall(function () 47 | lua:DoString([[t={} 48 | for i=1,]]..tostring(ran)..[[ do 49 | table.insert(t,string.char(0x63+i)) 50 | end 51 | 52 | allPrintData = {} 53 | function print(...) 54 | arg = { ... } 55 | if #arg == 0 then table.insert(allPrintData,"nil") return end 56 | local logAll = {} 57 | for i=1,select("#", ...) do 58 | table.insert(logAll, tostring(arg[i])) 59 | end 60 | table.insert(allPrintData,table.concat(logAll, "\t")) 61 | end 62 | ]]) 63 | lua:DoString(s) 64 | local lr = lua:DoString([[t={} 65 | for i=1,]]..tostring(ran)..[[ do 66 | table.insert(t,string.char(0x63+i)) 67 | end 68 | check = table.concat(t, ",") 69 | return table.concat(allPrintData, "\r\n") == check 70 | ]]) 71 | return lr and lr[0] 72 | end) 73 | if r then 74 | if not i then 75 | local lr = lua:DoString([[return table.concat(allPrintData, "\r\n")]])[0] 76 | local lc = lua:DoString([[return check]])[0] 77 | lua:Dispose()--销毁对象释放资源 78 | return "结果不符合要求哦,应输出\r\n"..lc.."\r\n但你输出的是\r\n"..lr 79 | end 80 | else 81 | lua:Dispose()--销毁对象释放资源 82 | return "代码报错啦,请检查是否有语法错误或运行时错误\r\n报错信息:\r\n".. 83 | (i:match("c# exception:XLua.LuaException: (.-)\r\n") or i) 84 | end 85 | lua:Dispose()--销毁对象释放资源 86 | return "" 87 | end 88 | -------------------------------------------------------------------------------- /LUATeach/Assets/script/levels/table.insert.lua: -------------------------------------------------------------------------------- 1 | 2 | title = "table删减" 3 | type = "写代码" 4 | infomation = "删减table元素" 5 | question = [[`table.insert (table, [pos ,] value)` 6 | 7 | 在(数组型)表 table 的 pos 索引位置插入 value,其它元素向后移动到空的地方。pos 的默认值是表的长度加一,即默认是插在表的最后。 8 | 9 | `table.remove (table [, pos])` 10 | 11 | 在表 table 中删除索引为 pos(pos 只能是 number 型)的元素,并返回这个被删除的元素,它后面所有元素的索引值都会减一。pos 的默认值是表的长度,即默认是删除表的最后一个元素。 12 | 13 | 下面是例子: 14 | 15 | ```lua 16 | local a = {1, 8} --a[1] = 1,a[2] = 8 17 | table.insert(a, 1, 3) --在表索引为1处插入3 18 | print(a[1], a[2], a[3]) 19 | table.insert(a, 10) --在表的最后插入10 20 | print(a[1], a[2], a[3], a[4]) 21 | 22 | -->打印的结果: 23 | 3 1 8 24 | 3 1 8 10 25 | ``` 26 | 27 | ```lua 28 | local a = { 1, 2, 3, 4} 29 | print(table.remove(a, 1)) --删除速索引为1的元素 30 | print(a[1], a[2], a[3], a[4]) 31 | 32 | print(table.remove(a)) --删除最后一个元素 33 | print(a[1], a[2], a[3], a[4]) 34 | 35 | -->打印的结果: 36 | 1 37 | 2 3 4 nil 38 | 4 39 | 2 3 nil nil 40 | ``` 41 | 42 | 请完成下面的任务: 43 | 44 | 已知`table`变量`t`, 45 | 46 | 去除`t`中的第一个元素 47 | 48 | 然后这时,在t的第三个元素前,加上一个`number`变量,值为`810` 49 | ]] 50 | code = [[ 51 | --请补全代码 52 | --已知变量为t 53 | --需要更改这个t的值 54 | ]] 55 | explain = "table十分灵活" 56 | 57 | check = function(s) 58 | local lua = CS.LUATeach.LuaEnv.LuaEnv.CreateLuaEnv() 59 | local r,i = pcall(function () 60 | lua:DoString([[t={1,2,3,4,5} 61 | ]]) 62 | lua:DoString(s) 63 | local lr = lua:DoString([[t={} 64 | check = true 65 | r = {2,3,810,4,5} 66 | for i=1,#t do 67 | if t[i] ~= r[i] then 68 | check = false 69 | break 70 | end 71 | end 72 | return check 73 | ]]) 74 | return lr and lr[0] 75 | end) 76 | if r then 77 | if not i then 78 | lua:Dispose()--销毁对象释放资源 79 | return "结果不符合要求哦" 80 | end 81 | else 82 | lua:Dispose()--销毁对象释放资源 83 | return "代码报错啦,请检查是否有语法错误或运行时错误\r\n报错信息:\r\n".. 84 | (i:match("c# exception:XLua.LuaException: (.-)\r\n") or i) 85 | end 86 | lua:Dispose()--销毁对象释放资源 87 | return "" 88 | end 89 | -------------------------------------------------------------------------------- /LUATeach/Assets/script/levels/table1.lua: -------------------------------------------------------------------------------- 1 | 2 | title = "数组" 3 | type = "写代码" 4 | infomation = "认识数组" 5 | question = [[数组,使用一个变量名,存储一系列的值 6 | 7 | 很多语言中都有数组这个概念,在Lua中,我们可以使用`table`(`表`)来实现这个功能 8 | 9 | 在Lua中,table是一个一系列元素的集合,使用大括号进行表示,其中的元素之间以逗号分隔,类似下面的代码: 10 | 11 | ```lua 12 | t = {1,3,8,5,4} 13 | ``` 14 | 15 | 我们可以直接使用元素的`下标`,来访问、或者对该元素进行赋值操作。 16 | 17 | 在上面的`table`变量`t`中,第一个元素的`下标`是`1`,第二个是`2`,以此类推。 18 | 19 | 我们可以用`变量名`+`中括号`,中括号里加上下标,来访问或更改这个元素,如下面的例子: 20 | 21 | ```lua 22 | t = {1,3,8,5,4} 23 | print(t[1]) --打印1 24 | print(t[3]) --打印8 25 | 26 | t[2] = 99 --更改第二个元素的值 27 | print(t[2]) --打印99 28 | 29 | t[6] = 2 --凭空新建第六个元素并赋值 30 | print(t[6]) --打印2 31 | 32 | print(t[10]) 33 | --因为不存在,打印nil 34 | ``` 35 | 36 | 以上就是table最简单的一个例子了,就是当作数组来用(注意,一般语言中的数组基本都为不可变长度,这里的table为可变长度) 37 | 38 | 下面你需要完成: 39 | 40 | 新建一个table,名为`cards`,存入1-10十个数字 41 | 42 | 将第3个元素与第7个元素交换 43 | 44 | 将第9个元素与第2个元素交换 45 | 46 | 增加第11个变量,值为23 47 | ]] 48 | code = [[ 49 | --请补全代码 50 | cards = 51 | ]] 52 | explain = "在Lua中,万物基于table,到后面你就明白了" 53 | 54 | check = function(s) 55 | 56 | if s:find("{1.*,.*9.*,.*7.*}") then 57 | return "请自觉做题,作弊没什么意义" 58 | end 59 | 60 | local lua = CS.LUATeach.LuaEnv.LuaEnv.CreateLuaEnv() 61 | local r,i = pcall(function () 62 | lua:DoString(s) 63 | local lr = lua:DoString([[ 64 | local result = true 65 | local rt = {1,9,7,4,5,6,3,8,2,10,23} 66 | for i=1,#rt do 67 | if cards[i] ~= rt[i] then 68 | result = false 69 | break 70 | end 71 | end 72 | return result 73 | ]]) 74 | return lr and lr[0] 75 | end) 76 | if r then 77 | if not i then 78 | lua:Dispose()--销毁对象释放资源 79 | return "cards里的数据不符合要求哦" 80 | end 81 | else 82 | lua:Dispose()--销毁对象释放资源 83 | return "代码报错啦,请检查是否有语法错误或运行时错误\r\n报错信息:\r\n".. 84 | (i:match("c# exception:XLua.LuaException: (.-)\r\n") or i) 85 | end 86 | lua:Dispose()--销毁对象释放资源 87 | return "" 88 | end 89 | -------------------------------------------------------------------------------- /LUATeach/Assets/script/levels/table2.lua: -------------------------------------------------------------------------------- 1 | 2 | title = "简单table" 3 | type = "写代码" 4 | infomation = "什么都能装的table" 5 | question = [[上一节里,我们将`table`来表示`数组`,实际上,`table`中可以包括`任意类型的数据` 6 | 7 | 比如我们可以在`table`中放置`number`和`string`数据,类似下面的代码: 8 | 9 | ```lua 10 | t = {"abc",223,",..a",123123} 11 | ``` 12 | 13 | 我们甚至能在里面放`function`变量 14 | 15 | ```lua 16 | t = { 17 | function() return 123 end, 18 | function() print("abc") end, 19 | function(a,b) return a+b end, 20 | function() print("hello world") end, 21 | } 22 | ``` 23 | 24 | 这些`table`访问每个元素的方式仍然是直接用下标,并且也能用下标来进行修改 25 | 26 | 下面你需要完成: 27 | 28 | 新建一个`table`,名为`funcList`,并实现以下功能 29 | 30 | 调用`funcList[1](a,b)`,返回a和b的乘积 31 | 32 | 调用`funcList[2](a,b)`,返回a减b的差 33 | 34 | 调用`funcList[3](a)`,返回a的相反数(-a) 35 | 36 | ]] 37 | code = [[ 38 | --请补全代码 39 | funcList = { 40 | 41 | } 42 | ]] 43 | explain = "万物基于table,你正在慢慢理解" 44 | 45 | check = function(s) 46 | local lua = CS.LUATeach.LuaEnv.LuaEnv.CreateLuaEnv() 47 | for n=1,20 do 48 | local a = math.random(1, 100) 49 | local b = math.random(1, 100) 50 | local r,i = pcall(function () 51 | lua:DoString(s) 52 | local lr = lua:DoString([[ 53 | return type(funcList[1]) == "function" and 54 | type(funcList[2]) == "function" and 55 | type(funcList[3]) == "function" and 56 | funcList[1](]]..tostring(a)..[[,]]..tostring(b)..[[) == ]]..tostring(a*b)..[[ and 57 | funcList[2](]]..tostring(a)..[[,]]..tostring(b)..[[) == ]]..tostring(a-b)..[[ and 58 | funcList[3](]]..tostring(a)..[[) == ]]..tostring(-a)) 59 | return lr and lr[0] 60 | end) 61 | if r then 62 | if not i then 63 | lua:Dispose()--销毁对象释放资源 64 | return "funcList里的函数不符合要求哦" 65 | end 66 | else 67 | lua:Dispose()--销毁对象释放资源 68 | return "代码报错啦,请检查是否有语法错误或运行时错误\r\n报错信息:\r\n".. 69 | (i:match("c# exception:XLua.LuaException: (.-)\r\n") or i) 70 | end 71 | end 72 | lua:Dispose()--销毁对象释放资源 73 | return "" 74 | end 75 | -------------------------------------------------------------------------------- /LUATeach/Assets/script/levels/table3.lua: -------------------------------------------------------------------------------- 1 | 2 | title = "table下标" 3 | type = "写代码" 4 | infomation = "自定义下标" 5 | question = [[在前两节,我们的`table`都只是一些简单的List(列表),每个元素的`下标`都是自动从1排列的 6 | 7 | 实际上,Lua中,下标可以直接在声明时进行指定,像下面这样: 8 | 9 | ```lua 10 | t = {6,7,8,9} 11 | --上面和下面的代码等价 12 | t = { 13 | [1] = 6, 14 | [2] = 7, 15 | [3] = 8, 16 | [4] = 9, 17 | } 18 | 19 | --甚至你可以跳过某些下标 20 | t = { 21 | [1] = 6, 22 | [3] = 7, 23 | [5] = 8, 24 | [7] = 9, 25 | } 26 | print(t[7]) 27 | --输出9 28 | 29 | --在声明后赋予元素值也是可以的 30 | t = {}--空的table 31 | t[101] = 10 32 | print(t[101]) 33 | --输出10 34 | ``` 35 | 36 | 下面你需要: 37 | 38 | 新建一个变量`t`,并按下面的格式声明 39 | 40 | 下标为`1`的元素,值为`123`(number) 41 | 42 | 下标为`13`的元素,值为`"abc"`(string) 43 | 44 | 下标为`666`的元素,值为`"666"`(string) 45 | ]] 46 | code = [[ 47 | --请补全代码 48 | t = { 49 | 50 | } 51 | ]] 52 | explain = "下一节将了解另一种下标" 53 | 54 | check = function(s) 55 | local lua = CS.LUATeach.LuaEnv.LuaEnv.CreateLuaEnv() 56 | local r,i = pcall(function () 57 | lua:DoString(s) 58 | local lr = lua:DoString([[return type(t) == "table" and t[1] == 123 and t[13] == "abc" and t[666] == "666"]]) 59 | return lr and lr[0] 60 | end) 61 | if r then 62 | if not i then 63 | lua:Dispose()--销毁对象释放资源 64 | return "t里的数据不符合要求哦" 65 | end 66 | else 67 | lua:Dispose()--销毁对象释放资源 68 | return "代码报错啦,请检查是否有语法错误或运行时错误\r\n报错信息:\r\n".. 69 | (i:match("c# exception:XLua.LuaException: (.-)\r\n") or i) 70 | end 71 | lua:Dispose()--销毁对象释放资源 72 | return "" 73 | end 74 | -------------------------------------------------------------------------------- /LUATeach/Assets/script/levels/table4.lua: -------------------------------------------------------------------------------- 1 | 2 | title = "table下标进阶" 3 | type = "写代码" 4 | infomation = "字符串下标" 5 | question = [[在上一节,我们学习了如何自定义下标,其实在Lua中,下标也可以是字符串,如下面的例子 6 | 7 | ```lua 8 | t = { 9 | ["apple"] = 10, 10 | banana = 12, 11 | pear = 6, 12 | } 13 | --使用["下标"] = 值 14 | --和 下标 = 值 15 | --都是正确写法 16 | --当第二种方式有歧义时,应该用第一种方式 17 | 18 | --可以用下面两种方式访问: 19 | print(t["apple"]) 20 | --输出10 21 | print(t.apple) 22 | --输出10 23 | --当第二种方式有歧义时,应该用第一种方式 24 | ``` 25 | 26 | 可见,在使用`string`作为下标时,`table`的灵活性提升了一共数量级。 27 | 28 | `string`作为下标时,也可以动态赋值: 29 | 30 | ```lua 31 | t = {} -- 空table 32 | t["new"] = "新的值" 33 | print(t.new) 34 | --输出 新的值 35 | ``` 36 | 37 | 下面你需要完成: 38 | 39 | 新建`table`变量`t` 40 | 41 | 下标为`apple`的元素,值为`123`(number) 42 | 43 | 下标为`banana`的元素,值为`"abc"`(string) 44 | 45 | 下标为`1@1`的元素,值为`"666"`(string) 46 | 47 | ]] 48 | code = [[ 49 | --请补全代码 50 | t = { 51 | 52 | } 53 | ]] 54 | explain = "你猜,为什么说Lua中,万物基于table呢?" 55 | 56 | check = function(s) 57 | local lua = CS.LUATeach.LuaEnv.LuaEnv.CreateLuaEnv() 58 | local r,i = pcall(function () 59 | lua:DoString(s) 60 | local lr = lua:DoString([[return type(t) == "table" and t.apple == 123 and t.banana == "abc" and t["1@1"] == "666"]]) 61 | return lr and lr[0] 62 | end) 63 | if r then 64 | if not i then 65 | lua:Dispose()--销毁对象释放资源 66 | return "t里的数据不符合要求哦" 67 | end 68 | else 69 | lua:Dispose()--销毁对象释放资源 70 | return "代码报错啦,请检查是否有语法错误或运行时错误\r\n报错信息:\r\n".. 71 | (i:match("c# exception:XLua.LuaException: (.-)\r\n") or i) 72 | end 73 | lua:Dispose()--销毁对象释放资源 74 | return "" 75 | end 76 | -------------------------------------------------------------------------------- /LUATeach/Assets/script/levels/table5.lua: -------------------------------------------------------------------------------- 1 | 2 | title = "Lua全局变量与table" 3 | type = "写代码" 4 | infomation = "了解_G" 5 | question = [[在前面我们知道了,在`table`中,可以直接用`table名[下标]`或`table名.string下标`来访问元素 6 | 7 | 实际上,在Lua中,所有的全局变量全部被存放在了一共大`table`中,这个`table`名为: 8 | 9 | `_G` 10 | 11 | 我们可以用下面的例子来示范: 12 | 13 | ```lua 14 | n = 123--新建变量 15 | print(n)--输出123 16 | print(_G.n)--输出123 17 | 18 | _G.abc = 1--相当于新建全局变量 19 | print(abc)--输出1 20 | 21 | _G["def"] = 23--相当于新建全局变量 22 | print(def)--输出23 23 | 24 | --甚至你可以像下面这样 25 | _G.print("hello") 26 | _G["print"]("world") 27 | ``` 28 | 29 | 现在,你明白为什么说`万物基于table`了吧? 30 | 31 | 你需要完成下面的任务: 32 | 33 | 已知有一个全局变量,名为`@#$` 34 | 35 | 请新建一个变量`result` 36 | 37 | 将`@#$`变量里的值赋值给`result` 38 | ]] 39 | code = [[ 40 | --请补全代码 41 | result = 42 | ]] 43 | explain = "table基础部分学习完毕" 44 | 45 | check = function(s) 46 | local lua = CS.LUATeach.LuaEnv.LuaEnv.CreateLuaEnv() 47 | local ran = math.random(1, 9999) 48 | local r,i = pcall(function () 49 | lua:DoString("_G[\"@#$\"] = "..tostring(ran)) 50 | lua:DoString(s) 51 | local lr = lua:DoString("return result == "..tostring(ran)) 52 | return lr and lr[0] 53 | end) 54 | if r then 55 | if not i then 56 | lua:Dispose()--销毁对象释放资源 57 | return "result里的数据不符合要求哦" 58 | end 59 | else 60 | lua:Dispose()--销毁对象释放资源 61 | return "代码报错啦,请检查是否有语法错误或运行时错误\r\n报错信息:\r\n".. 62 | (i:match("c# exception:XLua.LuaException: (.-)\r\n") or i) 63 | end 64 | lua:Dispose()--销毁对象释放资源 65 | return "" 66 | end 67 | -------------------------------------------------------------------------------- /LUATeach/Assets/script/levels/table6.lua: -------------------------------------------------------------------------------- 1 | 2 | title = "table小测试3" 3 | type = "写代码" 4 | infomation = "检查下前几堂课的学习" 5 | question = [[请新建一个名为`t`的`table`,满足以下要求 6 | 7 | t[10]可获得`number`类型数据`100` 8 | 9 | t.num可获得`number`类型数据`12` 10 | 11 | t.abc[3]可获得`string`类型数据`abcd` 12 | 13 | t.a.b.c可获得`number`类型数据`789` 14 | 15 | ]] 16 | code = [[ 17 | --请补全代码 18 | t = { 19 | 20 | } 21 | ]] 22 | explain = "看样子你已经理解了这部分内容了" 23 | 24 | check = function(s) 25 | local lua = CS.LUATeach.LuaEnv.LuaEnv.CreateLuaEnv() 26 | local r,i = pcall(function () 27 | lua:DoString(s) 28 | local lr = lua:DoString([[ 29 | return t[10] == 100 and 30 | t.num == 12 and 31 | type(t.abc) == 'table' and 32 | t.abc[3] == 'abcd' and 33 | type(t.a) == 'table' and 34 | type(t.a.b) == 'table' and 35 | t.a.b.c == 789 36 | ]]) 37 | return lr and lr[0] 38 | end) 39 | if r then 40 | if not i then 41 | lua:Dispose()--销毁对象释放资源 42 | return "result里的数据不符合要求哦" 43 | end 44 | else 45 | lua:Dispose()--销毁对象释放资源 46 | return "代码报错啦,请检查是否有语法错误或运行时错误\r\n报错信息:\r\n".. 47 | (i:match("c# exception:XLua.LuaException: (.-)\r\n") or i) 48 | end 49 | lua:Dispose()--销毁对象释放资源 50 | return "" 51 | end 52 | -------------------------------------------------------------------------------- /LUATeach/Assets/script/levels/while.lua: -------------------------------------------------------------------------------- 1 | 2 | title = "while循环" 3 | type = "写代码" 4 | infomation = "学习while循环语句" 5 | question = [[在实际功能实现中,经常会遇到需要循环运行的代码,比如从1到100填充table数据,我们可以直接用循环语句来实现 6 | 7 | 我们首先来学习`while`这个循环语法,整体的格式如下: 8 | 9 | ```lua 10 | while 继续循环判断依据 do 11 | 执行的代码 12 | end 13 | ``` 14 | 15 | 下面举一个例子,我们计算从1加到100的结果: 16 | 17 | ```lua 18 | local result = 0 19 | local num = 1 20 | 21 | while num <= 100 do 22 | result = result + num 23 | num = num + 1 24 | end 25 | 26 | print(result) 27 | ``` 28 | 29 | 上面的代码,就是当num≤100时,result不断地加num,并且num每次循环后自己加1 30 | 31 | 理解了上面的代码,我们来完成下面一个简单的任务吧: 32 | 33 | 已知两个number类型的变量`min`和`max` 34 | 35 | 请计算从`min`与`max`之间,所有`3的倍数`的`和` 36 | 37 | 新建一个变量`result`,将结果存到这个变量中 38 | ]] 39 | code = [[ 40 | --请补全代码 41 | result = 0 42 | 43 | while 请完善 do 44 | 45 | end 46 | ]] 47 | explain = "下一章将讲另一种循环" 48 | 49 | check = function(s) 50 | local lua = CS.LUATeach.LuaEnv.LuaEnv.CreateLuaEnv() 51 | local ran1 = math.random(1,100) 52 | local ran2 = math.random(500,800) 53 | local r,i = pcall(function () 54 | lua:DoString("min="..tostring(ran1).."\r\nmax="..tostring(ran2)) 55 | lua:DoString(s) 56 | lua:DoString("min="..tostring(ran1).."\r\nmax="..tostring(ran2)) 57 | local lr = lua:DoString([[ 58 | check = 0 59 | for i=min,max do 60 | if i%3 == 0 then 61 | check = check + i 62 | end 63 | end 64 | return result == check 65 | ]]) 66 | return lr and lr[0] 67 | end) 68 | if r then 69 | if not i then 70 | local lr = lua:DoString("return result")[0] 71 | local lc = lua:DoString("return check")[0] 72 | lua:Dispose()--销毁对象释放资源 73 | return "和不符合要求哦,"..tostring(ran1).."加"..tostring(ran2).."应为".. 74 | tostring(lc).. 75 | "但是你的结果为"..tostring(lr) 76 | end 77 | else 78 | lua:Dispose()--销毁对象释放资源 79 | return "代码报错啦,请检查是否有语法错误或运行时错误\r\n报错信息:\r\n".. 80 | (i:match("c# exception:XLua.LuaException: (.-)\r\n") or i) 81 | end 82 | lua:Dispose()--销毁对象释放资源 83 | return "" 84 | end 85 | -------------------------------------------------------------------------------- /LUATeach/Assets/script/log.lua: -------------------------------------------------------------------------------- 1 | --- 模块功能:系统日志记录,分级别日志工具 2 | -- @module log 3 | -- @author openLuat 4 | -- @license MIT 5 | -- @copyright openLuat 6 | -- @release 2017.09.26 7 | 8 | -- 定义日志级别常量,可在main入口全局指定 9 | -- 例如: LOG_LEVEL=log.LOGLEVEL_WARN 10 | LOG_SILENT = LOGLEVEL_TRACE; 11 | LOGLEVEL_TRACE = 0x01; 12 | LOGLEVEL_DEBUG = 0x02; 13 | LOGLEVEL_INFO = 0x03; 14 | LOGLEVEL_WARN = 0x04; 15 | LOGLEVEL_ERROR = 0x05; 16 | LOGLEVEL_FATAL = 0x06; 17 | 18 | -- 定义日志级别标签,分别对应日志级别的1-6 19 | local LEVEL_TAG = {'T', 'D', 'I', 'W', 'E', 'F'} 20 | local PREFIX_FMT = "[%s]-[%s]" 21 | 22 | local log = {} 23 | 24 | --- 内部函数,支持不同级别的log打印及判断 25 | -- @param level ,日志级别,可选LOGLEVEL_TRACE,LOGLEVEL_DEBUG等 26 | -- @param tag ,模块或功能名称(标签),作为日志前缀 27 | -- @param ... ,日志内容,可变参数 28 | -- @return nil 29 | -- @usage _log(LOGLEVEL_TRACE,tag, 'log content') 30 | -- @usage _log(LOGLEVEL_DEBUG,tag, 'log content') 31 | local function _log(level, tag, ...) 32 | -- INFO 作为默认日志级别 33 | local OPENLEVEL = LOG_LEVEL and LOG_LEVEL or LOGLEVEL_INFO 34 | -- 如果日志级别为静默,或设定级别更高,则不输出日志 35 | if OPENLEVEL == LOG_SILENT or OPENLEVEL > level then return end 36 | -- 日志打印输出 37 | local prefix = string.format(PREFIX_FMT, LEVEL_TAG[level], type(tag)=="string" and tag or "") 38 | print(prefix, ...) 39 | 40 | -- TODO,支持hookup,例如对某级别日志做额外处理 41 | -- TODO,支持标签过滤 42 | end 43 | 44 | --- 输出trace级别的日志 45 | -- @param tag ,模块或功能名称,作为日志前缀 46 | -- @param ... ,日志内容,可变参数 47 | -- @return nil 48 | -- @usage trace('moduleA', 'log content') 49 | function log.trace(tag, ...) 50 | _log(LOGLEVEL_TRACE, tag, ...) 51 | end 52 | 53 | --- 输出debug级别的日志 54 | -- @param tag ,模块或功能名称,作为日志前缀 55 | -- @param ... ,日志内容,可变参数 56 | -- @return nil 57 | -- @usage debug('moduleA', 'log content') 58 | function log.debug(tag, ...) 59 | _log(LOGLEVEL_DEBUG, tag, ...) 60 | end 61 | 62 | --- 输出info级别的日志 63 | -- @param tag ,模块或功能名称,作为日志前缀 64 | -- @param ... ,日志内容,可变参数 65 | -- @return nil 66 | -- @usage info('moduleA', 'log content') 67 | function log.info(tag, ...) 68 | _log(LOGLEVEL_INFO, tag, ...) 69 | end 70 | 71 | --- 输出warn级别的日志 72 | -- @param tag ,模块或功能名称,作为日志前缀 73 | -- @param ... ,日志内容,可变参数 74 | -- @return nil 75 | -- @usage warn('moduleA', 'log content') 76 | function log.warn(tag, ...) 77 | _log(LOGLEVEL_WARN, tag, ...) 78 | end 79 | 80 | --- 输出error级别的日志 81 | -- @param tag ,模块或功能名称,作为日志前缀 82 | -- @param ... ,日志内容,可变参数 83 | -- @return nil 84 | -- @usage error('moduleA', 'log content') 85 | function log.error(tag, ...) 86 | _log(LOGLEVEL_ERROR, tag, ...) 87 | end 88 | 89 | --- 输出fatal级别的日志 90 | -- @param tag ,模块或功能名称,作为日志前缀 91 | -- @param ... ,日志内容,可变参数 92 | -- @return nil 93 | -- @usage fatal('moduleA', 'log content') 94 | function log.fatal(tag, ...) 95 | _log(LOGLEVEL_FATAL, tag, ...) 96 | end 97 | 98 | return log 99 | -------------------------------------------------------------------------------- /LUATeach/Assets/script/strings.lua: -------------------------------------------------------------------------------- 1 | --- 模块功能:常用工具类接口 2 | -- @module utils 3 | -- @author openLuat 4 | -- @license MIT 5 | -- @copyright openLuat 6 | -- @release 2017.10.19 7 | 8 | --- 将Lua字符串转成HEX字符串,如"123abc"转为"313233616263" 9 | -- @string str 输入字符串 10 | -- @string[opt=""] separator 输出的16进制字符串分隔符 11 | -- @return hexstring 16进制组成的串 12 | -- @return len 输入的字符串长度 13 | -- @usage 14 | -- string.toHex("\1\2\3") -> "010203" 3 15 | -- string.toHex("123abc") -> "313233616263" 6 16 | -- string.toHex("123abc"," ") -> "31 32 33 61 62 63 " 6 17 | function string.toHex(str, separator) 18 | return str:gsub('.', function(c) 19 | return string.format("%02X" .. (separator or ""), string.byte(c)) 20 | end) 21 | end 22 | --- 将HEX字符串转成Lua字符串,如"313233616263"转为"123abc", 函数里加入了过滤分隔符,可以过滤掉大部分分隔符(可参见正则表达式中\s和\p的范围)。 23 | -- @string hex,16进制组成的串 24 | -- @return charstring,字符组成的串 25 | -- @return len,输出字符串的长度 26 | -- @usage 27 | -- string.fromHex("010203") -> "\1\2\3" 28 | -- string.fromHex("313233616263:) -> "123abc" 29 | function string.fromHex(hex) 30 | --滤掉分隔符 31 | local hex = hex:gsub("[%s%p]", ""):upper() 32 | return hex:gsub("%x%x", function(c) 33 | return string.char(tonumber(c, 16)) 34 | end) 35 | end 36 | 37 | --- 返回字符串tonumber的转义字符串(用来支持超过31位整数的转换) 38 | -- @string str 输入字符串 39 | -- @return str 转换后的lua 二进制字符串 40 | -- @return len 转换了多少个字符 41 | -- @usage 42 | -- string.toValue("123456") -> "\1\2\3\4\5\6" 6 43 | -- string.toValue("123abc") -> "\1\2\3\a\b\c" 6 44 | function string.toValue(str) 45 | return string.fromHex(str:gsub("%x", "0%1")) 46 | end 47 | 48 | --- 返回utf8编码字符串的长度 49 | -- @string str,utf8编码的字符串,支持中文 50 | -- @return number,返回字符串长度 51 | -- @usage local cnt = string.utf8Len("中国"),str = 2 52 | function string.utf8Len(str) 53 | local len = #str 54 | local left = len 55 | local cnt = 0 56 | local arr = {0, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc} 57 | while left ~= 0 do 58 | local tmp = string.byte(str, -left) 59 | local i = #arr 60 | while arr[i] do 61 | if tmp >= arr[i] then 62 | left = left - i 63 | break 64 | end 65 | i = i - 1 66 | end 67 | cnt = cnt + 1 68 | end 69 | return cnt 70 | end 71 | --- 返回数字的千位符号格式 72 | -- @number num,数字 73 | -- @return string,千位符号的数字字符串 74 | -- @usage loca s = string.formatNumberThousands(1000) ,s = "1,000" 75 | function string.formatNumberThousands(num) 76 | local k, formatted 77 | formatted = tostring(tonumber(num)) 78 | while true do 79 | formatted, k = string.gsub(formatted, "^(-?%d+)(%d%d%d)", '%1,%2') 80 | if k == 0 then break end 81 | end 82 | return formatted 83 | end 84 | 85 | --- 按照指定分隔符分割字符串 86 | -- @string str 输入字符串 87 | -- @string delimiter 分隔符 88 | -- @return 分割后的字符串列表 89 | -- @usage "123,456,789":split(',') -> {'123','456','789'} 90 | function string.split(str, delimiter) 91 | local strlist, tmp = {}, string.byte(delimiter) 92 | if delimiter == "" then 93 | for i = 1, #str do strlist[i] = str:sub(i, i) end 94 | else 95 | for substr in string.gmatch(str .. delimiter, "(.-)" .. (((tmp > 96 and tmp < 123) or (tmp > 64 and tmp < 91) or (tmp > 47 and tmp < 58)) and delimiter or "%" .. delimiter)) do 96 | table.insert(strlist, substr) 97 | end 98 | end 99 | return strlist 100 | end 101 | 102 | --- 返回utf8编码字符串的长度 103 | -- @string str,utf8编码的字符串,支持中文 104 | -- @return number,返回字符串长度 105 | -- @usage local cnt = string.utf8Len("中国"),str = 2 106 | function string.utf8Len(str) 107 | local len = #str 108 | local left = len 109 | local cnt = 0 110 | local arr = {0, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc} 111 | while left ~= 0 do 112 | local tmp = string.byte(str, -left) 113 | local i = #arr 114 | while arr[i] do 115 | if tmp >= arr[i] then 116 | left = left - i 117 | break 118 | end 119 | i = i - 1 120 | end 121 | cnt = cnt + 1 122 | end 123 | return cnt 124 | end 125 | -- 将一个字符转为urlEncode编码 126 | local function urlEncodeChar(c) 127 | return "%" .. string.format("%02X", string.byte(c)) 128 | end 129 | --- 返回字符串的urlEncode编码 130 | -- @string str,要转换编码的字符串 131 | -- @return str,urlEncode编码的字符串 132 | -- @usage string.urlEncode("####133") 133 | function string.urlEncode(str) 134 | return string.gsub(string.gsub(string.gsub(tostring(str), "\n", "\r\n"), "([^%w%.%- ])", urlEncodeChar), " ", "+") 135 | end 136 | -------------------------------------------------------------------------------- /LUATeach/Assets/script/sys.lua: -------------------------------------------------------------------------------- 1 | --- 模块功能:Luat协程调度框架 2 | -- @module sys 3 | -- @author openLuat 4 | -- @license MIT 5 | -- @copyright openLuat 6 | 7 | local sys = {} 8 | 9 | -- TaskID最大值 10 | local TASK_TIMER_ID_MAX = 0x1FFFFFFF 11 | -- msgId 最大值(请勿修改否则会发生msgId碰撞的危险) 12 | local MSG_TIMER_ID_MAX = 0x7FFFFFFF 13 | 14 | -- 任务定时器id 15 | local taskTimerId = 0 16 | -- 消息定时器id 17 | local msgId = TASK_TIMER_ID_MAX 18 | -- 定时器id表 19 | local timerPool = {} 20 | local taskTimerPool = {} 21 | --消息定时器参数表 22 | local para = {} 23 | --定时器是否循环表 24 | local loop = {} 25 | 26 | 27 | --- Task任务延时函数,只能用于任务函数中 28 | -- @number ms 整数,最大等待126322567毫秒 29 | -- @return 定时结束返回nil,被其他线程唤起返回调用线程传入的参数 30 | -- @usage sys.wait(30) 31 | function sys.wait(ms) 32 | -- 参数检测,参数不能为负值 33 | assert(ms > 0, "The wait time cannot be negative!") 34 | -- 选一个未使用的定时器ID给该任务线程 35 | if taskTimerId >= TASK_TIMER_ID_MAX then taskTimerId = 0 end 36 | taskTimerId = taskTimerId + 1 37 | local timerid = taskTimerId 38 | taskTimerPool[coroutine.running()] = timerid 39 | timerPool[timerid] = coroutine.running() 40 | -- 调用core的rtos定时器 41 | if 1 ~= apiStartTimer(timerid, ms) then log.debug("apiStartTimer error") return end 42 | -- 挂起调用的任务线程 43 | local message = {coroutine.yield()} 44 | if #message ~= 0 then 45 | apiStopTimer(timerid) 46 | taskTimerPool[coroutine.running()] = nil 47 | timerPool[timerid] = nil 48 | return table.unpack(message) 49 | end 50 | end 51 | 52 | --- Task任务的条件等待函数(包括事件消息和定时器消息等条件),只能用于任务函数中。 53 | -- @param id 消息ID 54 | -- @number ms 等待超时时间,单位ms,最大等待126322567毫秒 55 | -- @return result 接收到消息返回true,超时返回false 56 | -- @return data 接收到消息返回消息参数 57 | -- @usage result, data = sys.waitUntil("SIM_IND", 120000) 58 | function sys.waitUntil(id, ms) 59 | sys.subscribe(id, coroutine.running()) 60 | local message = ms and {sys.wait(ms)} or {coroutine.yield()} 61 | sys.unsubscribe(id, coroutine.running()) 62 | return message[1] ~= nil, table.unpack(message, 2, #message) 63 | end 64 | 65 | --- Task任务的条件等待函数扩展(包括事件消息和定时器消息等条件),只能用于任务函数中。 66 | -- @param id 消息ID 67 | -- @number ms 等待超时时间,单位ms,最大等待126322567毫秒 68 | -- @return message 接收到消息返回message,超时返回false 69 | -- @return data 接收到消息返回消息参数 70 | -- @usage result, data = sys.waitUntilExt("SIM_IND", 120000) 71 | function sys.waitUntilExt(id, ms) 72 | sys.subscribe(id, coroutine.running()) 73 | local message = ms and {sys.wait(ms)} or {coroutine.yield()} 74 | sys.unsubscribe(id, coroutine.running()) 75 | if message[1] ~= nil then return table.unpack(message) end 76 | return false 77 | end 78 | 79 | --- 创建一个任务线程,在模块最末行调用该函数并注册模块中的任务函数,main.lua导入该模块即可 80 | -- @param fun 任务函数名,用于resume唤醒时调用 81 | -- @param ... 任务函数fun的可变参数 82 | -- @return co 返回该任务的线程号 83 | -- @usage sys.taskInit(task1,'a','b') 84 | function sys.taskInit(fun, ...) 85 | arg = { ... } 86 | local co = coroutine.create(fun) 87 | assert(coroutine.resume(co, table.unpack(arg))) 88 | return co 89 | end 90 | 91 | ------------------------------------------ rtos消息回调处理部分 ------------------------------------------ 92 | --[[ 93 | 函数名:cmpTable 94 | 功能 :比较两个table的内容是否相同,注意:table中不能再包含table 95 | 参数 : 96 | t1:第一个table 97 | t2:第二个table 98 | 返回值:相同返回true,否则false 99 | ]] 100 | local function cmpTable(t1, t2) 101 | if not t2 then return #t1 == 0 end 102 | if #t1 == #t2 then 103 | for i = 1, #t1 do 104 | if table.unpack(t1, i, i) ~= table.unpack(t2, i, i) then 105 | return false 106 | end 107 | end 108 | return true 109 | end 110 | return false 111 | end 112 | 113 | --- 关闭定时器 114 | -- @param val 值为number时,识别为定时器ID,值为回调函数时,需要传参数 115 | -- @param ... val值为函数时,函数的可变参数 116 | -- @return 无 117 | -- @usage timerStop(1) 118 | function sys.timerStop(val, ...) 119 | arg = { ... } 120 | -- val 为定时器ID 121 | if type(val) == 'number' then 122 | timerPool[val], para[val], loop[val] = nil 123 | apiStopTimer(val) 124 | else 125 | for k, v in pairs(timerPool) do 126 | -- 回调函数相同 127 | if type(v) == 'table' and v.cb == val or v == val then 128 | -- 可变参数相同 129 | if cmpTable(arg, para[k]) then 130 | apiStopTimer(k) 131 | timerPool[k], para[k], loop[val] = nil 132 | break 133 | end 134 | end 135 | end 136 | end 137 | end 138 | 139 | --- 关闭同一回调函数的所有定时器 140 | -- @param fnc 定时器回调函数 141 | -- @return 无 142 | -- @usage timerStopAll(cbFnc) 143 | function sys.timerStopAll(fnc) 144 | for k, v in pairs(timerPool) do 145 | if type(v) == "table" and v.cb == fnc or v == fnc then 146 | apiStopTimer(k) 147 | timerPool[k], para[k], loop[k] = nil 148 | end 149 | end 150 | end 151 | 152 | --- 开启一个定时器 153 | -- @param fnc 定时器回调函数 154 | -- @number ms 整数,最大定时126322567毫秒 155 | -- @param ... 可变参数 fnc的参数 156 | -- @return number 定时器ID,如果失败,返回nil 157 | function sys.timerStart(fnc, ms, ...) 158 | arg = { ... } 159 | --回调函数和时长检测 160 | assert(fnc ~= nil, "sys.timerStart(first param) is nil !") 161 | assert(ms > 0, "sys.timerStart(Second parameter) is <= zero !") 162 | -- 关闭完全相同的定时器 163 | if arg.n == 0 then 164 | sys.timerStop(fnc) 165 | else 166 | sys.timerStop(fnc, table.unpack(arg)) 167 | end 168 | -- 为定时器申请ID,ID值 1-20 留给任务,20-30留给消息专用定时器 169 | while true do 170 | if msgId >= MSG_TIMER_ID_MAX then msgId = TASK_TIMER_ID_MAX end 171 | msgId = msgId + 1 172 | if timerPool[msgId] == nil then 173 | timerPool[msgId] = fnc 174 | break 175 | end 176 | end 177 | --调用底层接口启动定时器 178 | if apiStartTimer(msgId, ms) ~= 1 then log.debug("apiStartTimer error") return end 179 | --如果存在可变参数,在定时器参数表中保存参数 180 | if arg.n ~= 0 then 181 | para[msgId] = arg 182 | end 183 | --返回定时器id 184 | return msgId 185 | end 186 | 187 | 188 | --- 开启一个循环定时器 189 | -- @param fnc 定时器回调函数 190 | -- @number ms 整数,最大定时126322567毫秒 191 | -- @param ... 可变参数 fnc的参数 192 | -- @return number 定时器ID,如果失败,返回nil 193 | function sys.timerLoopStart(fnc, ms, ...) 194 | arg = { ... } 195 | local tid = sys.timerStart(fnc, ms, table.unpack(arg)) 196 | if tid then loop[tid] = ms end 197 | return tid 198 | end 199 | 200 | 201 | --- 判断某个定时器是否处于开启状态 202 | -- @param val 有两种形式 203 | --一种是开启定时器时返回的定时器id,此形式时不需要再传入可变参数...就能唯一标记一个定时器 204 | --另一种是开启定时器时的回调函数,此形式时必须再传入可变参数...才能唯一标记一个定时器 205 | -- @param ... 可变参数 206 | -- @return number 开启状态返回true,否则nil 207 | function sys.timerIsActive(val, ...) 208 | arg = { ... } 209 | if type(val) == "number" then 210 | return timerPool[val] 211 | else 212 | for k, v in pairs(timerPool) do 213 | if v == val then 214 | if cmpTable(arg, para[k]) then return true end 215 | end 216 | end 217 | end 218 | end 219 | 220 | 221 | ------------------------------------------ LUA应用消息订阅/发布接口 ------------------------------------------ 222 | -- 订阅者列表 223 | local subscribers = {} 224 | --内部消息队列 225 | local messageQueue = {} 226 | 227 | --- 订阅消息 228 | -- @param id 消息id 229 | -- @param callback 消息回调处理 230 | -- @usage subscribe("NET_STATUS_IND", callback) 231 | function sys.subscribe(id, callback) 232 | if type(id) ~= "string" or (type(callback) ~= "function" and type(callback) ~= "thread") then 233 | log.warn("warning: sys.subscribe invalid parameter", id, callback) 234 | return 235 | end 236 | if not subscribers[id] then subscribers[id] = {} end 237 | subscribers[id][callback] = true 238 | end 239 | 240 | --- 取消订阅消息 241 | -- @param id 消息id 242 | -- @param callback 消息回调处理 243 | -- @usage unsubscribe("NET_STATUS_IND", callback) 244 | function sys.unsubscribe(id, callback) 245 | if type(id) ~= "string" or (type(callback) ~= "function" and type(callback) ~= "thread") then 246 | log.warn("warning: sys.unsubscribe invalid parameter", id, callback) 247 | return 248 | end 249 | if subscribers[id] then subscribers[id][callback] = nil end 250 | end 251 | 252 | --- 发布内部消息,存储在内部消息队列中 253 | -- @param ... 可变参数,用户自定义 254 | -- @return 无 255 | -- @usage publish("NET_STATUS_IND") 256 | function sys.publish(...) 257 | arg = { ... } 258 | table.insert(messageQueue, arg) 259 | dispatch() 260 | end 261 | 262 | -- 分发消息 263 | function dispatch() 264 | while true do 265 | if #messageQueue == 0 then 266 | break 267 | end 268 | local message = table.remove(messageQueue, 1) 269 | if subscribers[message[1]] then 270 | for callback, _ in pairs(subscribers[message[1]]) do 271 | if type(callback) == "function" then 272 | callback(table.unpack(message, 2, #message)) 273 | elseif type(callback) == "thread" then 274 | assert(coroutine.resume(callback, table.unpack(message))) 275 | end 276 | end 277 | end 278 | end 279 | end 280 | ------------------------------------------ Luat 主调度框架 ------------------------------------------ 281 | function sys.tigger(param) 282 | if param < TASK_TIMER_ID_MAX then 283 | local taskId = timerPool[param] 284 | timerPool[param] = nil 285 | if taskTimerPool[taskId] == param then 286 | taskTimerPool[taskId] = nil 287 | assert(coroutine.resume(taskId)) 288 | end 289 | else 290 | local cb = timerPool[param] 291 | --如果不是循环定时器,从定时器id表中删除此定时器 292 | if not loop[param] then timerPool[param] = nil end 293 | if not cb then timerPool[param] = nil return end 294 | if para[param] ~= nil then 295 | cb(table.unpack(para[param])) 296 | if not loop[param] then para[param] = nil end 297 | else 298 | cb() 299 | end 300 | --如果是循环定时器,继续启动此定时器 301 | if loop[param] then apiStartTimer(param, loop[param]) end 302 | end 303 | end 304 | 305 | --协程外部触发 306 | tiggerCB = function (id,type,data) 307 | --log.debug("tigger",id,type,data:toHex()) 308 | if type == "uartRev" then--串口消息 309 | uartCB(data) 310 | elseif type == "cmd" then 311 | local result, info = pcall(function () 312 | load(data)() 313 | end) 314 | if result then 315 | log.info("console","run success") 316 | else 317 | log.info("console","run failed\r\n"..tostring(info)) 318 | end 319 | elseif id >= 0 then--定时器消息 320 | sys.tigger(id) 321 | end 322 | end 323 | 324 | log.info("sys","core loaded!") 325 | return sys 326 | -------------------------------------------------------------------------------- /LUATeach/FodyWeavers.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | xlua 5 | 6 | 7 | -------------------------------------------------------------------------------- /LUATeach/FodyWeavers.xsd: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | A list of assembly names to exclude from the default action of "embed all Copy Local references", delimited with line breaks 13 | 14 | 15 | 16 | 17 | A list of assembly names to include from the default action of "embed all Copy Local references", delimited with line breaks. 18 | 19 | 20 | 21 | 22 | A list of unmanaged 32 bit assembly names to include, delimited with line breaks. 23 | 24 | 25 | 26 | 27 | A list of unmanaged 64 bit assembly names to include, delimited with line breaks. 28 | 29 | 30 | 31 | 32 | The order of preloaded assemblies, delimited with line breaks. 33 | 34 | 35 | 36 | 37 | 38 | This will copy embedded files to disk before loading them into memory. This is helpful for some scenarios that expected an assembly to be loaded from a physical file. 39 | 40 | 41 | 42 | 43 | Controls if .pdbs for reference assemblies are also embedded. 44 | 45 | 46 | 47 | 48 | Embedded assemblies are compressed by default, and uncompressed when they are loaded. You can turn compression off with this option. 49 | 50 | 51 | 52 | 53 | As part of Costura, embedded assemblies are no longer included as part of the build. This cleanup can be turned off. 54 | 55 | 56 | 57 | 58 | Costura by default will load as part of the module initialization. This flag disables that behavior. Make sure you call CosturaUtility.Initialize() somewhere in your code. 59 | 60 | 61 | 62 | 63 | Costura will by default use assemblies with a name like 'resources.dll' as a satellite resource and prepend the output path. This flag disables that behavior. 64 | 65 | 66 | 67 | 68 | A list of assembly names to exclude from the default action of "embed all Copy Local references", delimited with | 69 | 70 | 71 | 72 | 73 | A list of assembly names to include from the default action of "embed all Copy Local references", delimited with |. 74 | 75 | 76 | 77 | 78 | A list of unmanaged 32 bit assembly names to include, delimited with |. 79 | 80 | 81 | 82 | 83 | A list of unmanaged 64 bit assembly names to include, delimited with |. 84 | 85 | 86 | 87 | 88 | The order of preloaded assemblies, delimited with |. 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. 97 | 98 | 99 | 100 | 101 | A comma-separated list of error codes that can be safely ignored in assembly verification. 102 | 103 | 104 | 105 | 106 | 'false' to turn off automatic generation of the XML Schema file. 107 | 108 | 109 | 110 | 111 | -------------------------------------------------------------------------------- /LUATeach/Global/Settings.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace LUATeach.Global 8 | { 9 | class Settings 10 | { 11 | private static string _code = Properties.Settings.Default.code; 12 | private static int _lastPass = Properties.Settings.Default.lastPass; 13 | 14 | /// 15 | /// 存储的测试代码 16 | /// 17 | public static string code 18 | { 19 | get 20 | { 21 | return _code; 22 | } 23 | set 24 | { 25 | _code = value; 26 | Properties.Settings.Default.code = value; 27 | Properties.Settings.Default.Save(); 28 | } 29 | } 30 | 31 | /// 32 | /// 上次通过的关卡 33 | /// 34 | public static int lastPass 35 | { 36 | get 37 | { 38 | if(_lastPass >= Global.Levels.LevelList.Count) 39 | return Global.Levels.LevelList.Count - 1; 40 | else 41 | return _lastPass; 42 | } 43 | set 44 | { 45 | if(value >= Global.Levels.LevelList.Count) 46 | _lastPass = Global.Levels.LevelList.Count - 1; 47 | else 48 | _lastPass = value; 49 | Properties.Settings.Default.lastPass = _lastPass; 50 | Properties.Settings.Default.Save(); 51 | } 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /LUATeach/Global/Utils.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace LUATeach.Global 8 | { 9 | class Utils 10 | { 11 | /// 12 | /// 读取软件资源文件内容 13 | /// 14 | /// 路径 15 | /// 文件内容字符串 16 | public static string GetAssetsFileContent(string path) 17 | { 18 | Uri uri = new Uri(path, UriKind.Relative); 19 | var source = System.Windows.Application.GetResourceStream(uri).Stream; 20 | byte[] f = new byte[source.Length]; 21 | source.Read(f, 0, (int)source.Length); 22 | return Encoding.UTF8.GetString(f); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /LUATeach/Images/clock_go.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxuuu/LUATeach/c975b210b88e10b50c6a590472b9d6380befd649/LUATeach/Images/clock_go.png -------------------------------------------------------------------------------- /LUATeach/Images/clock_go_32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxuuu/LUATeach/c975b210b88e10b50c6a590472b9d6380befd649/LUATeach/Images/clock_go_32.png -------------------------------------------------------------------------------- /LUATeach/Images/clock_play.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxuuu/LUATeach/c975b210b88e10b50c6a590472b9d6380befd649/LUATeach/Images/clock_play.png -------------------------------------------------------------------------------- /LUATeach/Images/download.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxuuu/LUATeach/c975b210b88e10b50c6a590472b9d6380befd649/LUATeach/Images/download.png -------------------------------------------------------------------------------- /LUATeach/Images/download_32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxuuu/LUATeach/c975b210b88e10b50c6a590472b9d6380befd649/LUATeach/Images/download_32.png -------------------------------------------------------------------------------- /LUATeach/Images/hand_point.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxuuu/LUATeach/c975b210b88e10b50c6a590472b9d6380befd649/LUATeach/Images/hand_point.png -------------------------------------------------------------------------------- /LUATeach/Images/icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxuuu/LUATeach/c975b210b88e10b50c6a590472b9d6380befd649/LUATeach/Images/icon.ico -------------------------------------------------------------------------------- /LUATeach/Images/update.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxuuu/LUATeach/c975b210b88e10b50c6a590472b9d6380befd649/LUATeach/Images/update.png -------------------------------------------------------------------------------- /LUATeach/LUATeach.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | Debug 7 | AnyCPU 8 | {7483AAE5-523C-4F92-94C4-759C49EAF7B6} 9 | WinExe 10 | LUATeach 11 | LUATeach 12 | v4.5 13 | 512 14 | {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 15 | 4 16 | true 17 | true 18 | 19 | 20 | 21 | publish\ 22 | true 23 | Disk 24 | false 25 | Foreground 26 | 7 27 | Days 28 | false 29 | false 30 | true 31 | 0 32 | 1.0.0.%2a 33 | false 34 | false 35 | true 36 | 37 | 38 | AnyCPU 39 | true 40 | full 41 | false 42 | bin\Debug\ 43 | DEBUG;TRACE 44 | prompt 45 | 4 46 | 47 | 48 | AnyCPU 49 | pdbonly 50 | true 51 | bin\Release\ 52 | TRACE 53 | prompt 54 | 4 55 | 56 | 57 | 1-svg.ico 58 | 59 | 60 | 61 | ..\packages\AdonisUI.1.11.0\lib\net40\AdonisUI.dll 62 | 63 | 64 | ..\packages\AdonisUI.ClassicTheme.1.11.0\lib\net40\AdonisUI.ClassicTheme.dll 65 | 66 | 67 | ..\packages\Autoupdater.NET.Official.1.5.7\lib\net40\AutoUpdater.NET.dll 68 | 69 | 70 | ..\packages\AppAutoUpdater.1.1.1\lib\net45\AutoUpdaterDotNet.dll 71 | 72 | 73 | ..\packages\Costura.Fody.4.1.0\lib\net40\Costura.dll 74 | 75 | 76 | ..\packages\FontAwesome.WPF.4.7.0.9\lib\net40\FontAwesome.WPF.dll 77 | 78 | 79 | ..\packages\AvalonEdit.6.0.0\lib\net45\ICSharpCode.AvalonEdit.dll 80 | 81 | 82 | ..\packages\SharpZipLib.1.2.0\lib\net45\ICSharpCode.SharpZipLib.dll 83 | 84 | 85 | ..\packages\Markdig.0.17.1\lib\net40\Markdig.dll 86 | 87 | 88 | ..\packages\Markdig.Wpf.0.3.0\lib\net40\Markdig.Wpf.dll 89 | True 90 | 91 | 92 | ..\packages\Newtonsoft.Json.12.0.2\lib\net45\Newtonsoft.Json.dll 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 4.0 108 | 109 | 110 | 111 | 112 | 113 | Lib\XLua.Mini.dll 114 | 115 | 116 | 117 | 118 | MSBuild:Compile 119 | Designer 120 | 121 | 122 | MSBuild:Compile 123 | Designer 124 | 125 | 126 | App.xaml 127 | Code 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | MainWindow.xaml 137 | Code 138 | 139 | 140 | Designer 141 | MSBuild:Compile 142 | 143 | 144 | Designer 145 | MSBuild:Compile 146 | 147 | 148 | Designer 149 | MSBuild:Compile 150 | 151 | 152 | Designer 153 | MSBuild:Compile 154 | 155 | 156 | Designer 157 | MSBuild:Compile 158 | 159 | 160 | Designer 161 | MSBuild:Compile 162 | 163 | 164 | 165 | 166 | CodingPage.xaml 167 | 168 | 169 | HomePage.xaml 170 | 171 | 172 | IntroducePage.xaml 173 | 174 | 175 | LuaEditorPage.xaml 176 | 177 | 178 | LuaListPage.xaml 179 | 180 | 181 | RightPage.xaml 182 | 183 | 184 | Code 185 | 186 | 187 | True 188 | True 189 | Resources.resx 190 | 191 | 192 | True 193 | Settings.settings 194 | True 195 | 196 | 197 | ResXFileCodeGenerator 198 | Resources.Designer.cs 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | SettingsSingleFileGenerator 237 | Settings.Designer.cs 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | False 264 | .NET Framework 3.5 SP1 265 | false 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 这台计算机上缺少此项目引用的 NuGet 程序包。使用“NuGet 程序包还原”可下载这些程序包。有关更多信息,请参见 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。 274 | 275 | 276 | 277 | 278 | -------------------------------------------------------------------------------- /LUATeach/Lib/XLua.Mini.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenxuuu/LUATeach/c975b210b88e10b50c6a590472b9d6380befd649/LUATeach/Lib/XLua.Mini.dll -------------------------------------------------------------------------------- /LUATeach/Lua.xshd: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | TODO 18 | FIXME 19 | 20 | 21 | HACK 22 | UNDONE 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | --- 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | --\[[=]*\[ 40 | \][=]*] 41 | 42 | 43 | 44 | 45 | -- 46 | 47 | 48 | 49 | " 50 | " 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | ' 59 | ' 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | \[[=]*\[ 68 | \][=]*] 69 | 70 | 71 | 72 | true 73 | false 74 | 75 | 76 | 77 | and 78 | break 79 | do 80 | else 81 | elseif 82 | end 83 | false 84 | for 85 | function 86 | if 87 | in 88 | local 89 | 90 | not 91 | or 92 | repeat 93 | return 94 | then 95 | true 96 | until 97 | while 98 | using 99 | continue 100 | 101 | 102 | 103 | break 104 | return 105 | 106 | 107 | 108 | local 109 | 110 | 111 | 112 | nil 113 | 114 | 115 | 116 | 117 | \b 118 | [\d\w_]+ # an identifier 119 | (?=\s*\() # followed by ( 120 | 121 | 122 | \b 123 | [\d\w_]+ # an identifier 124 | (?=\s*\") # followed by " 125 | 126 | 127 | \b 128 | [\d\w_]+ # an identifier 129 | (?=\s*\') # followed by ' 130 | 131 | 132 | \b 133 | [\d\w_]+ # an identifier 134 | (?=\s*\{) # followed by { 135 | 136 | 137 | \b 138 | [\d\w_]+ # an identifier 139 | (?=\s*\[) # followed by [ 140 | 141 | 142 | 143 | 144 | \b0[xX][0-9a-fA-F]+ # hex number 145 | | 146 | ( \b\d+(\.[0-9]+)? #number with optional floating point 147 | | \.[0-9]+ #or just starting with floating point 148 | ) 149 | ([eE][+-]?[0-9]+)? # optional exponent 150 | 151 | 152 | 153 | [?,.;()\[\]{}+\-/%*<>^+~!|&]+ 154 | 155 | 156 | -------------------------------------------------------------------------------- /LUATeach/LuaEnv/LuaApi.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace LUATeach.LuaEnv 8 | { 9 | class LuaApi 10 | { 11 | public static event EventHandler PrintLuaLog; 12 | /// 13 | /// 打印日志 14 | /// 15 | /// 日志内容 16 | public static void PrintLog(string log) 17 | { 18 | try 19 | { 20 | PrintLuaLog(log, EventArgs.Empty); 21 | } 22 | catch { } 23 | } 24 | 25 | 26 | /// 27 | /// utf8编码改为gbk的hex编码 28 | /// 29 | /// 30 | /// 31 | public static string Utf8ToAsciiHex(string input) 32 | { 33 | return BitConverter.ToString(Encoding.GetEncoding("GB2312").GetBytes(input)).Replace("-", ""); 34 | } 35 | 36 | /// 37 | /// 获取程序运行目录 38 | /// 39 | /// 主程序运行目录 40 | public static string GetPath() 41 | { 42 | return AppDomain.CurrentDomain.SetupInformation.ApplicationBase; 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /LUATeach/LuaEnv/LuaEnv.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace LUATeach.LuaEnv 8 | { 9 | class LuaEnv 10 | { 11 | /// 12 | /// 新建Lua虚拟机,并绑定好各项接口 13 | /// 14 | /// 15 | public static XLua.LuaEnv CreateLuaEnv() 16 | { 17 | var lua = new XLua.LuaEnv(); 18 | //utf8转gbk编码的hex值 19 | lua.DoString("apiUtf8ToHex = CS.LUATeach.LuaEnv.LuaApi.Utf8ToAsciiHex"); 20 | //获取软件目录路径 21 | lua.DoString("apiGetPath = CS.LUATeach.LuaEnv.LuaApi.GetPath"); 22 | //输出日志 23 | lua.DoString("apiPrintLog = CS.LUATeach.LuaEnv.LuaApi.PrintLog"); 24 | 25 | //运行初始化文件 26 | lua.DoString(Global.Utils.GetAssetsFileContent("/Assets/script/head.lua")); 27 | lua.DoString(Global.Utils.GetAssetsFileContent("/Assets/script/strings.lua")); 28 | lua.Global.SetInPath("log", lua.DoString(Global.Utils.GetAssetsFileContent("/Assets/script/log.lua"))[0]); 29 | lua.Global.SetInPath("JSON", lua.DoString(Global.Utils.GetAssetsFileContent("/Assets/script/JSON.lua"))[0]); 30 | 31 | return lua; 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /LUATeach/LuaEnv/LuaRunEnv.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.IO; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading; 8 | using System.Threading.Tasks; 9 | 10 | namespace LUATeach.LuaEnv 11 | { 12 | class LuaRunEnv 13 | { 14 | public static event EventHandler LuaRunError;//报错的回调 15 | private static XLua.LuaEnv lua = null; 16 | private static CancellationTokenSource tokenSource = null; 17 | private static Dictionary pool = 18 | new Dictionary();//timer回调池子 19 | private static List toRun = new List();//待运行的池子 20 | 21 | public static bool isRunning = false; 22 | 23 | private static void addTigger(int id, string type = "timer", string data = "") 24 | { 25 | toRun.Add(new LuaPool { id = id, type = type, data = data }); 26 | } 27 | 28 | 29 | /// 30 | /// 实时跑一段lua代码 31 | /// 32 | /// 33 | public static void RunCommand(string l) 34 | { 35 | addTigger(-1, "cmd", l); 36 | } 37 | 38 | private static void runTigger() 39 | { 40 | try 41 | { 42 | while (true) 43 | { 44 | Task.Delay(1).Wait(); 45 | if (tokenSource.IsCancellationRequested) 46 | return; 47 | if (toRun.Count > 0) 48 | { 49 | try 50 | { 51 | lua.Global.Get("tiggerCB").Call(toRun[0].id, toRun[0].type, toRun[0].data); 52 | } 53 | catch(Exception le) 54 | { 55 | LuaApi.PrintLog("回调报错:\r\n" + le.Message); 56 | } 57 | if (tokenSource.IsCancellationRequested) 58 | return; 59 | toRun.RemoveAt(0); 60 | } 61 | } 62 | } 63 | catch (Exception ex) 64 | { 65 | StopLua(ex.ToString()); 66 | } 67 | } 68 | 69 | /// 70 | /// 新建定时器 71 | /// 72 | /// 编号 73 | /// 时间(ms) 74 | public static int StartTimer(int id,int time) 75 | { 76 | CancellationTokenSource timerToken = new CancellationTokenSource(); 77 | if (pool.ContainsKey(id)) 78 | { 79 | try 80 | { 81 | pool[id].Cancel(); 82 | pool.Remove(id); 83 | } 84 | catch { } 85 | } 86 | pool.Add(id, timerToken); 87 | Task.Run(() => 88 | { 89 | Task.Delay(time).Wait(); 90 | if (timerToken == null || timerToken.IsCancellationRequested) 91 | return; 92 | if (tokenSource.IsCancellationRequested) 93 | return; 94 | addTigger(id); 95 | pool.Remove(id); 96 | }, timerToken.Token); 97 | return 1; 98 | } 99 | 100 | /// 101 | /// 停止定时器 102 | /// 103 | /// 编号 104 | public static void StopTimer(int id) 105 | { 106 | if (pool.ContainsKey(id)) 107 | { 108 | try 109 | { 110 | pool[id].Cancel(); 111 | pool.Remove(id); 112 | } 113 | catch { } 114 | } 115 | } 116 | 117 | /// 118 | /// 停止运行lua 119 | /// 120 | public static void StopLua(string ex) 121 | { 122 | LuaRunError(null, EventArgs.Empty); 123 | if (ex != "") 124 | LuaApi.PrintLog("lua代码报错了:\r\n" + ex); 125 | else 126 | LuaApi.PrintLog("lua代码已停止"); 127 | foreach(var v in pool) 128 | { 129 | v.Value.Cancel(); 130 | } 131 | isRunning = false; 132 | tokenSource.Cancel(); 133 | pool.Clear(); 134 | lua = null; 135 | } 136 | 137 | /// 138 | /// 新建一个新的lua虚拟机 139 | /// 140 | public static void New(string script) 141 | { 142 | if (tokenSource != null) 143 | tokenSource.Dispose(); 144 | tokenSource = new CancellationTokenSource();//task取消指示 145 | 146 | lua = LuaEnv.CreateLuaEnv(); 147 | isRunning = true; 148 | Task.Run(() => 149 | { 150 | try 151 | { 152 | lua.Global.SetInPath("sys", lua.DoString(Global.Utils.GetAssetsFileContent("/Assets/script/sys.lua"))[0]); 153 | lua.DoString("apiStartTimer = CS.LUATeach.LuaEnv.LuaRunEnv.StartTimer"); 154 | lua.DoString("apiStopTimer = CS.LUATeach.LuaEnv.LuaRunEnv.StopTimer"); 155 | lua.DoString("setRunMaxSeconds(-1)"); 156 | lua.DoString(script); 157 | } 158 | catch (Exception ex) 159 | { 160 | StopLua(ex.Message); 161 | } 162 | runTigger(); 163 | }, tokenSource.Token); 164 | } 165 | } 166 | 167 | 168 | class LuaPool 169 | { 170 | public int id { get; set; } 171 | public string type { get; set; } 172 | public string data { get; set; } 173 | } 174 | } 175 | -------------------------------------------------------------------------------- /LUATeach/MainWindow.xaml: -------------------------------------------------------------------------------- 1 | 10 | 11 | 31 | 35 | 39 | 42 | 43 | 44 | 51 | 28 | 36 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /LUATeach/Pages/HomePage.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.Windows; 7 | using System.Windows.Controls; 8 | using System.Windows.Data; 9 | using System.Windows.Documents; 10 | using System.Windows.Input; 11 | using System.Windows.Media; 12 | using System.Windows.Media.Imaging; 13 | using System.Windows.Navigation; 14 | using System.Windows.Shapes; 15 | 16 | namespace LUATeach.Pages 17 | { 18 | /// 19 | /// HomePage.xaml 的交互逻辑 20 | /// 21 | public partial class HomePage : Page 22 | { 23 | public HomePage() 24 | { 25 | InitializeComponent(); 26 | } 27 | 28 | private void RunLuaButton_Click(object sender, RoutedEventArgs e) 29 | { 30 | this.NavigationService.Navigate(new Uri("Pages/LuaEditorPage.xaml", UriKind.Relative)); 31 | } 32 | 33 | private void LuatButton_Click(object sender, RoutedEventArgs e) 34 | { 35 | MessageBox.Show("Comming soon!"); 36 | } 37 | 38 | private void LearnLuaButton_Click(object sender, RoutedEventArgs e) 39 | { 40 | this.NavigationService.Navigate(new Uri("Pages/LuaListPage.xaml", UriKind.Relative)); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /LUATeach/Pages/IntroducePage.xaml: -------------------------------------------------------------------------------- 1 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 29 | 30 | 31 | 32 | 33 | 34 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /LUATeach/Pages/LuaListPage.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.Windows; 7 | using System.Windows.Controls; 8 | using System.Windows.Data; 9 | using System.Windows.Documents; 10 | using System.Windows.Input; 11 | using System.Windows.Media; 12 | using System.Windows.Media.Imaging; 13 | using System.Windows.Navigation; 14 | using System.Windows.Shapes; 15 | 16 | namespace LUATeach.Pages 17 | { 18 | /// 19 | /// LuaListPage.xaml 的交互逻辑 20 | /// 21 | public partial class LuaListPage : Page 22 | { 23 | public LuaListPage() 24 | { 25 | InitializeComponent(); 26 | } 27 | 28 | List levels = new List(); 29 | 30 | private void BackButton_Click(object sender, RoutedEventArgs e) 31 | { 32 | this.NavigationService.Navigate(new Uri("Pages/HomePage.xaml", UriKind.Relative)); 33 | } 34 | 35 | private void Page_Loaded(object sender, RoutedEventArgs e) 36 | { 37 | Task.Run(() => 38 | { 39 | for (int i = 0; i < Global.Levels.LevelList.Count; i++) 40 | { 41 | levels.Add(new Level 42 | { 43 | id = i + 1, 44 | title = Global.Levels.LevelList[i].title, 45 | type = Global.Levels.LevelList[i].type, 46 | infomation = Global.Levels.LevelList[i].infomation, 47 | enable = i <= Global.Settings.lastPass, 48 | }); 49 | } 50 | 51 | this.Dispatcher.Invoke(new Action(delegate 52 | { 53 | Loading.Visibility = Visibility.Collapsed; 54 | levelsList.ItemsSource = levels; 55 | })); 56 | }); 57 | 58 | } 59 | 60 | private void Button_Click(object sender, RoutedEventArgs e) 61 | { 62 | Level data = ((Button)sender).Tag as Level; 63 | Global.Levels.selected = data.id - 1; 64 | 65 | this.NavigationService.Navigate(new Uri($"Pages/{Global.Levels.GetPage()}.xaml", UriKind.Relative)); 66 | } 67 | 68 | private void ContinueButton_Click(object sender, RoutedEventArgs e) 69 | { 70 | Global.Levels.selected = Global.Settings.lastPass; 71 | this.NavigationService.Navigate(new Uri($"Pages/{Global.Levels.GetPage()}.xaml", UriKind.Relative)); 72 | } 73 | } 74 | 75 | 76 | class Level 77 | { 78 | public int id { get; set; } 79 | public string title { get; set; } 80 | public string type { get; set; } 81 | public string infomation { get; set; } 82 | public bool enable { get; set; } 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /LUATeach/Pages/RightPage.xaml: -------------------------------------------------------------------------------- 1 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 |