You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从integer()类型变量获取特定值?及解决二十一点游戏手牌计算的System.IndexOutOfRangeException异常

解决二十一点手牌计算的数组越界问题与Integer数组取值疑问

让我们一步步拆解你的问题,先搞定那个烦人的数组越界异常,再解答你关于Integer数组的疑问。

一、先解决System.IndexOutOfRangeException异常

你的异常根源完全出在这行代码上:

value += p.getHand(i).getValue(i)

这里犯了一个逻辑混淆的错误:你把遍历手牌的循环变量i,同时当成了getValue()返回的Integer数组的索引,但这两个索引完全没有关联:

  • 循环变量i是手牌列表的索引(从0到手牌总数-1)
  • getValue()返回的数组是单张牌的可选数值(比如Ace是{1,11},2是{2},JQK是{10}),它的长度最多是2(只有Ace有两个值)

举个实际例子:当你遍历到第二张牌(i=1),如果这张牌是2,它的getValue()数组长度只有1,此时访问getValue(1)就会直接超出数组的合法索引范围(数组只有索引0),触发越界异常。

修复后的基础版check函数

如果只是想先实现基础的手牌总值计算(暂时把Ace按最小数值1计算),可以直接取数组的第一个元素:

Public Shared Function check(p As Player) As Integer
    Dim value As Integer = 0
    For i = 0 To p.length() - 1
        ' 取每张牌数值数组的第一个元素
        value += p.getHand(i).getValue()(0)
    Next
    Return value
End Function

进阶版:符合二十一点规则的Ace双值处理

二十一点中Ace可以灵活切换1或11(尽量不爆牌),我们可以优化逻辑来实现这个规则:

Public Shared Function check(p As Player) As Integer
    Dim total As Integer = 0
    Dim aceCount As Integer = 0

    ' 第一步:先按最小数值计算所有牌,统计Ace的数量
    For Each card In p.getHand()
        Dim cardValues = card.getValue()
        If cardValues.Length = 2 Then ' 判定是Ace牌
            aceCount += 1
            total += cardValues(0) ' 先按1计算
        Else
            total += cardValues(0)
        End If
    Next

    ' 第二步:尝试把Ace从1换成11,只要总价值不超过21就替换
    While aceCount > 0 AndAlso total + 10 <= 21
        total += 10
        aceCount -= 1
    End While

    Return total
End Function

二、关于Integer()类型变量的取值疑问

Integer()在VB.NET里是整数数组,要获取里面的元素需要用索引访问,格式是数组变量(索引):

  • 数组的索引从0开始,最大合法索引是数组.Length - 1
  • 比如Ace牌的数值数组是{1,11},取1用values(0),取11用values(1)
  • 必须确保索引在合法范围内,否则就会触发你遇到的IndexOutOfRangeException

举个简单的示例代码:

' Ace牌的数值数组
Dim aceValues() As Integer = {1, 11}
Dim minAceValue As Integer = aceValues(0) ' 得到1
Dim maxAceValue As Integer = aceValues(1) ' 得到11

' 2牌的数值数组
Dim twoValues() As Integer = {2}
Dim cardValue As Integer = twoValues(0) ' 得到2

额外的小建议

为了让代码更符合.NET的命名规范,你可以做两个小调整:

  1. 把Player类里的length()方法改成只读属性:
Public ReadOnly Property HandCount As Integer
    Get
        Return hand.Count
    End Get
End Property

调用时用p.HandCount代替p.length(),代码可读性更强。

  1. 把Card类的getValue()属性改成Values,和.NET的属性命名风格保持统一。

内容的提问来源于stack exchange,提问作者It was me DIO

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 07:52:33